Hello!<br><br>I wrote a simple shader to mask a sprite with a color, as seen below:<br><img alt="" src="https://dl.dropboxusercontent.com/u/32519866/Forum_pictures/Godot_forum_picture.png" title="Image: https://dl.dropboxusercontent.com/u/32519866/Forum_pictures/Godot_forum_picture.png"><br><br>The image above was taken from the editor and it seems the shader works correctly. However, when the project is running the green circle (the sprite that holds the shader) disappears. I have test a few other colors and they all yield the same result. Here a picture of the project running:<br><img src="https://dl.dropboxusercontent.com/u/32519866/Forum_pictures/Godot_forum_picture_2.png" alt="" title="Image: https://dl.dropboxusercontent.com/u/32519866/Forum_pictures/Godot_forum_picture_2.png"><br><br>Here is the shader code for the fragment (vertex and lighting are empty):<br>

uniform color object_color; if (texscreen(SCREEN_UV).rgb != object_color.rgb) { COLOR.a = 0; } else { COLOR.a = tex(TEXTURE, UV).a; }<br>

<br>Any help as to what could be the issues would be appreciated.

What happens if you set the alpha to 0.5 instead? Does the entire sprite disappear anyway? Does it become semi-transparent?

@Alex-doc - I just tried setting the alpha to half, and the sprite becomes semi-transparent.<br><br>I also tried changing the sprite from a solid white sprite (that was modulated green) to a colored sprite, which didn't change anything. Changing the sprite it's trying to use as a mask (the blue square) to a colored sprite also didn't change anything.<br><br>I discovered that changing the value of the object color field on the shader while it is running using the remote inspector seemed to make the shader perform normally. I can even set it to the exact same color, and it works. Not really sure why though. Maybe the object color is being overridden somewhere?<br><br>When I opened the project in the editor the circle was gone until I changed the value, then the shader works normally in the editor. So I thought the editor wasn't saving the color correctly.<br><br>I looked at the material file with a text editor, and the only difference I could find was the saved color's red value was slightly more precise. Changing the value to the exact same value outputted by a print statement caused the shader to not work in the editor, and didn't change anything when to project was running.<br><br>Not sure if it makes any difference, but I'm using Godot 2.1 on Linux.<br><br>Thanks for the help!

I figured it out!<br><br>Huge thanks to @Alex-doc!<br><br>It turns out the problem lies in floating point values and rounding!<br><br>Here's how I fixed it. I have little experience on shaders, and how Godot works internally, so this is mostly my observations and speculations.<br>

(Once again, huge thanks to @Alex-doc for suggesting to change the alpha value!)<br><br>When I changed the alpha value to 0.5, I observed that the sprite was at half it's alpha value despite being in the proper colored mask. That lead me to try a few things, like changing the sprites modulation values (both the circle and the mask), and using textured sprites, with no apparent difference.<br><br>However, when I opened the project to test the different alpha value, I noticed the shader wasn't working in the editor. The only way I could get it to work again was to change the object color field in the material, then it worked like normal. It even worked when all I did was set the color to the exact same color using the color picker. This led me to try using the remote inspector and changing the object color in the material at run time. Similar to the editor, it worked fine and the shader was performing like it should.<br><br>I thought that was rather strange, and wondered if the editor wasn't saving the color properly, so I dug around the project files using a text editor. After making my way from the scene to the shader material, I discovered that the color saved was a more precise in number than what I printed out. So I double checked the printed color (the mask color) and noticed that they didn't match up. The printed color was rounded down a few digits more than the saved color.<br><br>It hit me that perhaps the color inputted to the material gets truncated down when it's loaded, and so the colors aren't exactly the same in value. So I adjusted the shader to work in a range instead of a equal check, and it works in the editor and while running! Problem solved!<br><br>I'm guessing that GD script (or C++) uses less bits in its floating point values than Godot's shader language. I think that's why the shader wasn't working and why it works now.<br>

<br>Here's the updated shader!<br>(released under CC0&nbsp;in case anyone is wondering)<br>

uniform color Object_color;<br>uniform float Range;<br><br>if (texscreen(SCREEN_UV).r &gt;= Object_color.r - Range &amp;&amp; texscreen(SCREEN_UV).r &lt;= Object_color.r + Range)<br>{<br>&nbsp; &nbsp;&nbsp;if (texscreen(SCREEN_UV).g &gt;= Object_color.g - Range &amp;&amp; texscreen(SCREEN_UV).g &lt;= Object_color.g + Range)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if (texscreen(SCREEN_UV).b &gt;= Object_color.b - Range &amp;&amp; texscreen(SCREEN_UV).b &lt;= Object_color.b + Range)<br>&nbsp; &nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; COLOR.a = tex(TEXTURE, UV).a;<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; COLOR.w = 0;<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; COLOR.w = 0;<br>&nbsp; &nbsp; }<br>}<br>else<br>{<br>&nbsp; &nbsp; COLOR.w *= 0;<br>}<br>

<br>

So the solution was to set to 0.0 instead of 0 ?<br><br>AFAIK integers should not be supported in shaders, this might be a bug, each non float should be forced to float or double or throw an error, not rounded to an automatic type as it happens in script...<br><br>

The solution was checking in a range, instead of doing an equal check. This is more or less what I think is happening, though I'm not sure if this is 100% correct (I'm making some assumptions on what is happening behind the scenes):<br><br>When a material is saved, floats are saved with certain precision, say 0.123456 for example. When the editor and runtime loads the data from the file(s) it rounds the float down, to something like 0.1235. (NOTE: I know this because I looked in the scene and material files and noted that it was of higher precision than the same color I printed in runtime)<br><br>The way the old version of the shader was working, is that it was doing an equal check. Using the example of 0.123456 again. The shader is checking if 0.123456 is equal to 0.1235, which will never be equal (since it dropped 0.000056 due to rounding). The reason the color white worked is because white has a value of 1 for each of the colors (red, green, and blue). Black probably would have also worked since black has a value of zero for each color. Any color inbetween black and white though would have this rounding issue though since the way Godot stores colors is in values between 1 and 0.<br><br>The way to get around the issue is rather than checking if two values are equal instead check if they are equal within a range. Using the above example again, the shader looks to see if 0.123456 is within the range of 0.1235 and 0.1234, assuming the inputted range is 0.001. Because this accounts for the rounding, the shader works for any color (though in reality it works for any range of colors within the inputted range value)<br><br><br>I don't think the problem is with integers, but rather with floats and their bit length. The major issue is that Godot's engine and runtime don't account for the difference in float precision. I couldn't find anything in the documentation about what bit length Godot's shader language is, but as far as I can tell, it would appear that the shader language has 2-4 more bits than GD script (or C++). Interestingly, I also checked raw floats, instead of colors, and they also held this same issue. It would seem that any floats in shaders are rounded down on load time, regardless of what data structure they are in! I'm not sure if this is a bug, or perhabs I missed where it was mentioned, but it is at least rather confusing.<br><br>Hopefully this explains what I observed was happening! I was rather surprised that the issue was all in a rounding error!<br>

I see, float comparison is always source of problems.

Nice catch though! I think they are probably rounded down for compatibility or to avoid glitches..

6 years later