- Home /
Shading problems with cubes next to each other?
Hello Community, I've ran into a very odd problem a few weeks ago already and didn't manage to fix it so far. I'm making a 2D Sidescrolling jumping game, where players can create their levels out of blocks. The problem is, that whenever the player moves, there are odd flashing artifacts (black lines) appearing inbetween some of the cubes. Since this only appears to be the case when changing the cameras position I suppose the shading messes things up.
Here is a screenshot
I'm combining the meshes of the blocks in order to reduce drawcalls. I tried changing the rendering mode from forward to anything else, didn't work. Spent hours of tweaking the light to minimize the effect, but unless i turn off shaders completely it remains. Slowly I'm running out of ideas, maybe some of you can help? Thanks in advance!
Are you referring to the shadows? if you turn shadows off for your main light do you still get the same problem?
The long black line. $$anonymous$$any of these keep flashing while the camera moves.
Have you find a proper solution ? Im having the same issue on 3d AND 2d.
https://www.youtube.com/watch?v=0FIQ6qqBhbc
check 0:22 blue line s appear when moving the camera...
Answer by duck · May 31, 2013 at 02:35 PM
What you're seeing is basically due to floating point imprecision, combined with (as Olly says) non-welded vertices. This can occur even if you're sure there are no imprecisions in your own measurements: Your blocks may be exactly 1m square, and you may have used grid snapping to position them exactly 1m apart, but Unity's engine (and most other 3d engines) will be storing the object positions and vertex positions as floating point values.
Because they're separate objects and not welded vertices, Unity has no idea that these two vertices are supposed to be in exactly the same spot, and the calculations used to compute the on-screen position may result in tiny differences in value.
Consider the vertex shown in yellow for object A and B:
If this mesh was welded, Unity would calculate one position for the shared vert. But since they're not welded, and two separate objects each have a vert in that position, Unity will perform two separate floating point calculations - one for object A and one for object B.
Most of these blocks appear to line up exactly, from most camera positions. But from the occasional unfortunate position, the exact value for A's position plus its vertex at (0.5,0.5,-0.5) might be slightly different to object B's position plus its vertex at (-0.5,0.5,-0.5) . The result is that Unity shows a tiny gap, within which you can see the shadowed side of cube A. If these were planes instead of cubes, you'd be able to see through the pixel-wide gap.
A workaround might be to make these blocks a tiny amount larger than your grid size, so they overlap slightly. For 1x1x1 bricks, a scale of (1.001, 1.001, 1.001) would be enough. This would mean as a side effect that you might be able to see the slight overlap when looking very closely, but from your screenshot, it might be acceptable for your purpose.
That was what I thought too, so I had the blocks sized to 1.02 for some time, but it didn't show any effect. 1.001 doesn't cut it as well :S But thanks for explaining the theory behind! Very interesting
In practice, rounding usually gives close enough values that you never see an artifact. Yes, "inevitable rounding" is real. But only for large numbers and/or complex math.
I just for-loop spawned a 10x10 grid of oddly-sized (0.28x0.28) blocks from an oddball start point around x=100. No flicker at all. Deliberately adding an extra 0.0001 gap gave a very tiny flicker from seams. Adding an extra 0.001 gap gave visible black seams, but smaller than the drawing above.
$$anonymous$$oving out to x=1,000 (and using correct math) gave no flickers. Finally, at x=10,000 every seam had an obvious flicker.
Thats strange, Im storing the level data in a file which holds positions and block id's. When a level is loaded I instantiate corresponding block at the stored position. I found that this position was a floated number due to the relative position to the parent object holding the blocks. I moved the parent to 0,0,0 and rounded the x y and z coords of the position vector so now it seems as if everything should be perfectly alligned.
One oddity I have though is, that the actual cubes holding that are a child of the instantiated object not centered in the spawned objects, but ins$$anonymous$$d moved down by 0.5 and right by -0.5.
I will try to round the offset of the cube inside the parent object.
Additionally I will try to make a grid of unity natives like you did just to check wether its not my unity screwing with me.
Results : soon
Rounding didn't do the trick. Also, spawning a 10x10 grid of primitive cubes via for loop gave me the same flicker, they were all 1x1x1 sized and started to spawn from 0,0,0. I probably missed the magical math that you did, since I merely iterated over i and j from 0 to 9 and then spawned the cubes at those x and y positions.
Answer by OllyNicholson · May 31, 2013 at 02:07 PM
These seams are most likely the result of adjacent vertices (e.g. minute gaps between your user placed blocks) they will often display artefacts between them as a result of the shadows calculating minute gaps between the geometry, the only sure way to prevent this is to make sure the geometry is welded e.g water tight - which I appreciate is difficult to do with dynamic content.
To minimise it you can try things like angling the direction of the light, increasing shadow quality settings and increasing the accuracy by which your blocks snap to each other. Obviously you also want to make sure the blocks are consistent scales etc.
The Size of all blocks is 1,1,1 and the editor places them in a grid at exactly x,y,15/16, x and y being only ints without decimals which should be pretty much water tight I think.
I've found if you pause, select the model, zoom in exa$$anonymous$$e the mesh, recheck the transforms... it very often comes down to a placement error.
Basically all those cubes share one combined mesh (if theyre of the same material). The original meshes have shadows turned off because i was not sure wether they would interfere
Answer by LicketyCut · Apr 05, 2021 at 08:58 PM
I have encountered a similar problem.
I played with position, scale and shaders with no luck.
Then I started adjusting project Quality settings but that didn't help either.
Finally, I looked at my camera settings.
Changing Occlusion Culling had no effect.
But Setting HDR and MSAA to "Use Graphics Settings" did the trick for me!
I think it is the MSAA that did it but why not just enable them both?
I hope this saves someone a bit of time playing with settings.
Your answer
Follow this Question
Related Questions
Help Turning Sprites into 3D Objects and Casting Shadows 1 Answer
Lighting works for iPad but not iPhone? 0 Answers
[Shader] No Fog on Particles/Standard Unlit 0 Answers
How to get 2d lighting data in shadergraph? 0 Answers
unity_LightColor[1] and up are 0 with 2 point lights near the object. 0 Answers