Material precission

I have a Material in which I want to show different textures depending on a value. If that value is close to a whole number, it breaks the material, cause 2 textures are shown.

Lets say I have the value 6.5. Floor(6.5)=6. If(value=6) → Show Texture6. Works fine.

Is the value already close to a whole numer, or is a whole number, e.g. 6.99 or 7.0, the value will vary and Floor() will respectively return 6 or 7. That will result in two different textures.

I read about a similar problems in other threads, but these seem to be old and came to no solution.

I only would need values in range from 0…9, no fractal.
The value returned by Floor() seems to be stable, at least Floor(6.5) will result in 6 and just one texture is shown.
Floor(whole number) will fail, cause the returned value might result in two different.

You are running into typical floating point precision issues. Have in mind that equals to comparison is unreliable and it is quite expected that floor will return higher value than expected if used on number like 6.9999999

Thanks Deathray,

that´s what Im aware of. The question is how to get around that. I don´t need values with such a high precision, just values from 0.0…9.9. But how would I go bout cutting all that fractal positions? How to get from 6.999999 to 6.9? Floor(6.9999910)/10 will not work, cause 6.999910 can result in 7*10.

Can a whole numer as 7 flicker to 6.99999? Or just the other way around (6.99999->7)?

Unreal has this tutorial:

That is what I want to achieve. The example does work, because the channel value is 0 or 1(0.99999). The Lerp does care out the value, but doen´t matter in the result.

Instead of multiple channels, I have a single number in range of 0…99. But diving that number and inserting the result into Lerp.Alpha will result in values between 0…1 (e.g. 0.5) → does not work. Taking node as Floor/If will result in hard edges that can flicker.

You could use series of two conditionals. Use control value in range 0-1.
If control value <0.1 → show texture 1
if control value <0.2 and control value >=0.1 → show texture 2
if control value <0.3 and control value >=0.2 ->show texture 3

Alternatively, do a saturate(frac(Control value)-Texture index), where control value is a float ranging from 0 to n and texture index is a const with values 0,1…n for each texture

However, you should really describe what exactly are you trying to achieve and why. It is common, that there is a better, easier, and more efficient way.

Thanks, will try that.

There is not much more to tell, but will try. I want to spawn actors, lets say a cube, with different textures on it. Because of how the system works, the Material always needs to stay the same, exactly the same, no childing or what ever. When spawning, a random number is generated and inserted into the material using an UV-Channel. Number in range of 0…99. The UV channels looks like this: {XXYYZZ.0, AABB.0}
X/Y/Z/B = Random 0…99. A = ScaleOfObject. This is multipurpose and the RandomNumbers are used for other stuff as well.

There is no additional UV channel that can be used. The numbers have four empty digits in whole that can be used like the RGB channels in the unreal example, that could provide 16 different values when going binary (0111, 0101, 0100, 0011, …). The amount of textures is not fix and is up to the designer what to use. Taking the RandomNumber in range of 0…99 the Designer could simply decide on his own how many different textures he needs. Distribution of the different textures should be somewhat equal, what the binary solution does not provide when working with e.g. 15 textures, cause the last binary number needs to be assigned as well. Resulting in one texture that come up twice as often.

Maybe in the future there is a problem like this, so better get it over with right now.

Will try your solution.

Edit:
Your solution works like a charm.

But why? What is the difference? Can´t 0.5 flicker to 0.4999? Is it because float are always saved as 0.69999999 with exponent and transforming to 6.99999 will cause the precission issue?

For what it takes, float precision is highest near zero and lowest near its upper limit.

Considering your task, be advised that there is no way you can realistically use 99 textures and have decent performance at the same time. I Think this task is perfect candidate for texture atlas, where you would store all the numbers. In this case, it is not the texture you need to swap, but texture coordinates instead. There even is a built in material function for that. It is called flipbook.

“Appendix” … alright, gues need to consume that one.

Thanks for the Texture Atlas and Flipbook node. Have known Texture Atlas already, just did not know that it is called like that and good to have that “decrypt” node.

Thanks for the link and the help, always appreciated.