3
\$\begingroup\$

I'm drawing a grid, pretty much like one can see in the Unity editor itself or any 3D-editor, many 3D-related applications and some games. But it doesn't look pretty in my case.

enter image description here

I put a few random objects to make perspective more readable.

Please also see it full-size for clearer view on the artifacts at a distance.

How grid is rendered

  • Whole grid is one big plane.
  • There is texture representing one cell.
  • The cell is multiplicated by tiling.

How there are different line thicknesses on the picture?

It's just 3 planes (each with one grid) with different settings on top of each other. I could leave only one, but 3 grids demonstrate my problem better.

Additional details:

  • Mipmap is disabled (grid cells disappear very soon over distance when it's enabled).
  • Trilinear filtration and maximum aniso are set (looks worse otherwise).

My guess

I think over distance lines get to be thinner than a pixel, especially under shallow angle (hence “verticals” lines look better than “horizontal”.

Conclusion

Grid rendering is obviously done many times before me, so I presume it should be pretty much wide knowledge how to draw them prettily. I tried to google it, but any query formulation I tried led only to completely unrelated stuff. I have a bit of ideas what I can try, but I believe it would be reinventing the wheel.

P.S.: I'm using Unity engine, but I believe the engine is irrelevant.


Plane simple blurring suggested by user29244 and Thebluefish really makes huge difference: greatly improved grid Biggest lines are too blurry now, but it's irrelevant, because easy to fix. Note that I had to enable mipmaping if you're trying to reproduce it.

\$\endgroup\$
  • 1
    \$\begingroup\$ Have you considered anti-aliasing? \$\endgroup\$ – Thebluefish Jan 16 '15 at 20:00
  • \$\begingroup\$ I have, but even after max anti-aliasing is set the difference is negligible. \$\endgroup\$ – Maxim Kamalov Jan 16 '15 at 20:03
  • \$\begingroup\$ Ah I see that you are using textures. Try setting your texture filtering instead. \$\endgroup\$ – Thebluefish Jan 16 '15 at 20:23
  • \$\begingroup\$ Texture filtering is set to max level already. \$\endgroup\$ – Maxim Kamalov Jan 16 '15 at 20:24
  • \$\begingroup\$ Thanks everybody for your great answers and suggestions. I have to choose only one solution (and mark only one answer), but it's nice to know other alternatives (maybe even I'll switch between solutions later or use them elsewhere). \$\endgroup\$ – Maxim Kamalov Jan 17 '15 at 13:14
2
\$\begingroup\$

You can't avoid this problem, you can try super sampling to make it less jarring ... but high frequency + high contrast works very bad in quantisize space. I go around this with a very small bit of blurring on the texture, it's counter intuitive but then you have more chance than a pixel pick a blur value and make the line looks antialiased on the texture, assuming you never get close enough that the pixel ratio to texel ration sell the trick.

More: https://elementalray.wordpress.com/tag/artifact/

\$\endgroup\$
  • 1
    \$\begingroup\$ Or, instead of blurring the texture, wouldn't it be better to have a shader that blurs it depending on how far away it is from the camera? \$\endgroup\$ – Paul Manta Jan 16 '15 at 20:50
  • 1
    \$\begingroup\$ @PaulManta: Since it's too obviously done before me by many people, do you maybe have any additional details or links near at hand? \$\endgroup\$ – Maxim Kamalov Jan 16 '15 at 21:38
1
\$\begingroup\$

The way you draw them, you have big cells that contain 10x10 small cells. Would it be acceptable to draw only the big cells when they're at a certain distance from the camera? That would be one possibility. Another would be to actually draw lines, like in a wireframe mesh. They are always exactly one pixel wide. That's all the ideas i have right now.

\$\endgroup\$
  • 1
    \$\begingroup\$ I thought about drawing lines, but how can I make them not ignore Z-order? \$\endgroup\$ – Maxim Kamalov Jan 16 '15 at 20:44
1
\$\begingroup\$

For this kind of thing, it depends on what your goals is. If you're looking to ensure that lines are 1 pixel wide, then you could draw the grid using lines instead of textured triangles:

However with ensuring that lines are 1 pixel wide, when they're so far away that the individual grid spaces are less than 1px, it will look like a solid:

With your existing solution, you may be able to get better results by setting the texture filtering to Anisotropic with an appropriate ratio.

Another option would be to sub-divide your grid into smaller grid spaces. Using either mipmapping or different textures, you could separate your grid texture into 3 different grid sizes based off distance:

  • level 1 - 10x10
  • level 2 - 5x5
  • level 3 - 1x1

Alternatively, manually blurring the line would be another option. It should make the line "wider" without it being too thick.

Finally, a custom shader could do the trick. You could develop a shader that samples the lines appropriately depending on distance from the camera. This option would give you the most fine-tuned approach, though it is much more complex to setup for newer developers.

\$\endgroup\$
  • \$\begingroup\$ I prefer faster (to implement) solution, because it's just a prototype for now. But I'm not exactly novice developer, so I would like if you elaborate more regarding custom shader approach. \$\endgroup\$ – Maxim Kamalov Jan 16 '15 at 20:54
  • \$\begingroup\$ Unfortunately I am still a novice with shaders. I have seen a similar approach in another project, so I know that it can be done, but I am not familiar with its implementation. \$\endgroup\$ – Thebluefish Jan 16 '15 at 21:15
1
\$\begingroup\$

This might be a bit overkill for this specific problem, but might want to have a look at Humus's Phone-wire anti-aliasing:

http://www.humus.name/index.php?page=3D&ID=89

The idea is to adjust the radius of the wire to make sure it does not get smaller than a pixel wide. If the wire's radius would make it smaller than a pixel, it clamps the width to a pixel and instead fades with an alpha value corresponding to the radius reduction ratio. For example, if the wire is deemed to be half a pixel large at current distance, it clamps width to a full pixel and sets coverage to 0.5 instead. While the technique solves the problem of aliasing due to thin geometry, it does not address the general problem of jaggies; however, your regular MSAA will take care of that. With both enabled you get a very natural looking wire at any distance.

A similar approach could likely be used on other aliasing prone geometry based on thin geometry, such as antenna towers, pipes and railings.

If you could apply it to your problem, I believe it would solve it in the best way possible.

(I realize that the question is old and the original poster has probably moved on by now, but it might be of use to someone else reading this.)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.