Search Unity

Wireframe with backside culling

Discussion in 'General Graphics' started by btschumy, Jan 20, 2021.

  1. btschumy

    btschumy

    Joined:
    Jul 31, 2019
    Posts:
    93
    I have a Galaxy visualization app that I originally wrote for iOS and Mac using Apple's SceneKit. One of the things I do is show a spherical volume around the Galaxy that is draw in wireframe mode. Here is what it looks like:

    Wireframe-SceneKit.jpeg

    In Unity, I don't think there is a "wireframe" mode for drawing individual objects. So instead I created a spherical mesh in Blender and then added a wireframe modifier to it. My understanding is that this is not a true wireframe drawing mode but rather traverses the segments creating line objects of some in the model.

    Here is what this looks like:

    Wireframe-Unity.jpg

    One big difference is that the line on the "backside" are not drawn in the SceneKit version. I prefer this because it makes the image less busy and complicated. SceneKit has a "isDoubleSided" property of the material that makes this happen when false.

    Is there a way to get the same effect in Unity? I think culling is on by default but since this isn't a true wireframe, I think it is rendering the backside line anyway.

    Any thoughts on how I can achieve the same effect in Unity?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Yeah, don't do that. There's no way to cull the "back face" lines because that's created a mesh of thin cylinders in the shape of the wireframe. You are correct in assuming that it is likely already is culling the back faces of that mesh, the back faces of the cylinders.

    There is... sort of.

    Unity has a GL.wireframe setting that can be enabled / disabled to have things render as wireframe. However there's no built in option to allow you to enable that for a single object. The closest you can get would be to use something like an OnPostRender script that enables wireframe rendering, render a mesh manually using Graphics.DrawMeshNow() and then disable wireframe rendering.

    An alternative would be to manually draw the lines using GL.LINES, but there isn't really any significant benefit to using that over the above technique. Apart from there being a free asset on the store that does this:
    https://assetstore.unity.com/packages/tools/modeling/mesh-wireframe-renderer-58433

    There is an easier option. But it requires a bit more work depending on the platforms you want to support. On desktop PCs you can use a shader like this one that automatically renders a wireframe using a geometry shader:
    https://github.com/Chaser324/unity-wireframe

    If you're curious how that shader works, there's a tutorial on what it's doing here:
    https://catlikecoding.com/unity/tutorials/advanced-rendering/flat-and-wireframe-shading/

    The problem is that requires geometry shaders, something that many mobile devices do not have, and something that Apple has explicitly chosen to not support on either Macs or iDevices. However the only thing the geometry shader is doing is passing barycentric information for each triangle to the fragment shader. This data can be added to mesh vertex data to begin with, removing the need for geometry shaders entirely. There are several assets on the Unity Asset Store that do just that.

    This one has been around for ages, is well reviewed, and has a ton of features:
    https://assetstore.unity.com/packages/vfx/shaders/wireframe-shader-181386

    Alternatively this one appears to be a lot more bare bones, but should accomplish the same task, but may not have a shader that will produce the exact result you're looking to have:
    https://assetstore.unity.com/packages/vfx/shaders/simple-wireframe-67386
     
    JoNax97 likes this.
  3. btschumy

    btschumy

    Joined:
    Jul 31, 2019
    Posts:
    93
    Thanks for the information. I had previously tried the mesh-wireframe-renderer you linked to on the Assets store and was not able to get it to work. However, I gave it another go and I think I did figure out how to use it. You have to attach his script to the GameObject you want a wireframe rendering of. Then disable the mesh renderer for the object so you don't see the surface as well.

    As you intimated, it does not solve the backside culling problem, but it might be easier to use than creating a wireframe in Blender.

    It does seem like the wireframe rendering it generates has significant aliasing that would be good to remove if possible. Any thoughts on how I might do this? Also, I'd probably prefer the wires to be a bit thicker than they are currently draw. I will poke around to see if that is possible but I'd like to hear any ideas anyone has.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    It's easily "the worst" asset of the ones I listed above for what you're looking to do. If you want "back face" culling of the sphere with that asset you'd need to modify the code to skip the lines for edges that are facing away from the camera. Like your blender wireframe renderer, the concept of "back faces" is removed since it's directly drawing the triangle edges as GPU line geometry, and line geometry has no back face.

    Line geometry may or may not support anti-aliasing via MSAA depending on the GPU. Line drawing is usually considered a Pro level GPU feature, so consumer GPUs have for a long time being intentionally hamstrung when it comes to rendering lines. In the 90's soldiering a wire to a consumer GPU would enable line AA and improve rendering performance by a few 1000 %, but these days it's done deeper in the chip silicon. Things like line width is one of those things most consumer GPUs just can't do. As I said, it's the "worst" option. It'll draw a wireframe, and be more efficient that the blender wireframe mesh, but there's not really a lot you can do with it.


    The second to last asset I linked to, the updated version of the "Amazing" Wireframe Shader, will be able to everything you need. It'll do anti-aliasing with or without MSAA or post process anti-aliasing. It'll let you control the line width. And it'll render way faster than any of the other options on any hardware.
     
  5. btschumy

    btschumy

    Joined:
    Jul 31, 2019
    Posts:
    93
    Thanks again. I think I'm under control now. Appreciate it.

    Bill