Precision problems?

Hi guys,

I created a Unity project with some 3d tiles. Every tile has a size of 4.0f on the x- and z-axis (width and depth). I place different tiles in the scene to create a level on scene loading. The tiles are not textured, because I use vertex colors to get a blocky look.

When targetting windows phone, desktop or webplayer everything works fine. When targetting WSA and deploying to a Microsoft Surface RT I got some small gaps (max. 1 pixel, dark lines) between adjacent tiles. I know about floating point precision and such things, but the strange thing is, that this happens only on the Surface not on other devices.

Does anyone has suggestions how to fix this?

If the tiles are static, create them as a single mesh dynamically instead, you can then easily close the gaps and make it perfect.

Most of the tiles are static, but not all :frowning:

My only suggestion would be make the tiles a fraction bigger on Windows RT with conditional compilation, it’s probably more likely to do with either AntiAliasing hiding the issue on other devices (and on some the resolution to screen ratio makes it unnoticeable) or an issue with DX9 as RT is only shader model 2.

Thanks for this advice. I thought about this yesterday, too.

Is it enough to increase the scale property of the transform after creating the tile instance from prefab?

No, don’t do that, it will greatly impact performance, loop through the vertices in the mesh and * them by your scale increase, then just update the original mesh.

Or create a second prefab for Windows RT, then spawn that instead.

Thanks again :slight_smile:

Just to understand right (and maybe learn something new): Why does modifying the transform greatly impact performance? Isn’t the transform the world matrix of the mesh to be rendered? When it is the world matrix every vertex of the mesh has to be multiplied by this matrix in the vertex shader every frame. Changing position, rotation or scale doesn’t change the execution time of the matrix multiplication.

When you multiply every vertex in the mesh by this world matrix and store the result in the mesh you’re able to save this multiplication in the vertex shader. Is this a optimization unity does for static meshes?

I would imagine that scale would be an applied transformation change that is done for the object on ‘every’ frame… hence the performance impact. If we’re only talking about a couple dozen polys, it is probably not a huge deal, but should probably be fixed with an alternative prefab for RT.

I would first double check the original tile, and attempt to make them so that the verts are ‘snapped’ to a precision that is workable for your environment. You may also check that when placing them in Unity, you are using vertex snapping to align everything up (which you may have already, but I know I forget and approximate stuff when testing).

It’s because you get dynamic batching if the scale is 1,1,1 but if it’s not it won’t batch thus increasing draw calls…so unless you batch it yourself,then you’ll get issues…

If you use static batching, then it will static batch before your code runs to re-scale so this wouldn’t work either, so best and simplest to modify the mesh, the code is really pretty simple and something everyone should learn…many uses for game optimisations!

Oh and FYI, Why does modifying the transform greatly impact performance? Isn’t the transform the world matrix of the mesh to be rendered? When it is the world matrix every vertex of the mesh has to be multiplied by this matrix in the vertex shader every frame.

Well, based on how it used to work in DirectX which is probably the same method in unity, the verts are render and transformed by a Matrix passed to the shader. The issue is if you use Dynamic Batching which you’d probably need to use to achieve the effect of dynamically scaling, it will cancel out the dynamic batching…this is because all the verts get pre-transformed outside of the shader on the CPU, but for performance reasons it does not do the scaling.

Of course if you want static batching, just batch them yourself to a single static mesh…even better with this method you can use the same verts at joins or at least use an identical position and get perfect seems.