We are trying to optimize our project and have a bunch of non-uniform scaled objects which we want fix.
The problem lies in detecting those objects; we have over 10 000 objects in our scenes and all localScale vector3’s components are floats.
Comparing 2 floats (obj1.localScale.x == obj1.localScale.y obj1.localScale.x == obj1.localScale.z) doesn’t work as it gives false positives. Using Mathf.Approximately is not precise enough; (0.6889498 == 0.6889499 == 0.688945).
What is the real tolerance of the engine towards non-uniform scaling?
Is Mathf.Approximately a garantee that the mesh is uniformly scaled?
Do the values have to be up to a certain decimal to not be instanciated as seperate mesh in the memory?
public static bool FuzzyEquals(float a, float b, float epsilon)
{
return Mathf.Abs(a - b) < epsilon;
}
now just pass in some value of tolerance for epsilon you find acceptable. A value of 0.0001 is a common tolerance.
The thing about floats is that the error of it is machine specific (it’s called the machine epsilon). So the error can be different on different computers depending on the hardware and software. For instance an AMD chip and an Intel chip will vary slightly… or if someone is on a chip that doesn’t have an fpu (highly rare in this day and age) and the value is generated in software.
Question, what do you do if the object isn’t uniform? If you just set it to be equal to say x… why even test? Just set all objects to its uniform scale.
I might just do that, but for epsilon to have any meaningfull value I need to know the engine’s tollerance for when it makes a seperate instance in the memory.
Unfortunately we can’t just go over every single object to check if the automatic scaling broke the scenes. Some objects are shared between scenes, others not, some are obscure in places almost no-one goes to. It has to be taken care on a case-by-case basis for QA. (lets say the object has a correct x scale but not y/z, then we need to make sure the original 3d source file has it’s xform resetted in an appropriate scaling)
The cutoff point for the engine’s static mesh instancing is of 0.0000x (^-05). Anything higher will create a sperate mesh in the application’s memory.
This is also much much higher than Mathf.Epsilon and also higher than Mathf.Approximately. Which means it is either hardcoded into the engine’s static batcher or dependant on the user’s computer CPU.
In conclusion, if you have scaled objects in your scene (and a bunch of them), you should consider creating a scripts that automatically re-scales them if they are under 0.000x (^-04) of difference, change being barely visible.
The change is quite minimal though. In my scene, if I scale my 3000 objects so they get instanced, my RAM usage increases by about 8Mb; 675Mb → 683Mb.