Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question How to render meshes at same height without z-fighting?

Discussion in 'Scripting' started by i9fasc7, Nov 30, 2023.

  1. i9fasc7

    i9fasc7

    Joined:
    Jun 7, 2018
    Posts:
    74
    Hello everyone,

    I am currently playing around with the idea of hexagons whose sides are connected by bezier curves. I took inspiration from the board game Indigo and the result creates a nice and intricate pattern.

    Then I thought that just one curve starting from one edge and connecting to another (forming a total of 3 bezier curves for the 6 edges of a hexagon) is not enough and changed my code so that I can have a any amount of curves connecting two edges of the hexagon.
    upload_2023-11-30_20-52-8.png

    Not soon after I stumbled across a problem called z-fighting because all my curve meshes have the same height value while only the hexagon is created further back in the scene. I tried to prevent the z-fighting of the curves by changing the height value of each individual curve (for example the Curve1 has an offset from the mesh of 0.1f, Curve2 has an offset from the mesh of 0.2, etc.) but that only looks good if I have an orthographic camera is facing directly towards the hexagon and the curves. Even a slight rotation of the camera makes it obvious to see that the curves have different height values.
    upload_2023-11-30_20-52-26.png

    Of course, by decreasing the offset values of the individual curves from each other and the mesh I can preserve the illusion of the curve meshes being on the “same” height and in front of the hexagon. But while this can work for one hexagon this approach fails if another hexagon is added and there are a lot of curves. It is possible that on the first hexagon the Curve1 with a height of 0.00001f is “touching“ the Curve9 of another hexagon with an offset of 0.00009f and viewed at an angle I can see the difference in height.
    upload_2023-11-30_20-52-43.png

    I tried decreasing the offset even further and tried around with the clipping planes of the camera, but having a small offset to make the curves appear on the same height even viewed from an angle and preventing z-fighting seems not possible for my current level of understanding.

    Is there another way of having the curves rendered on top of each other while appearing on the same height without z-fighting?

    I tried a multi camera approach with one camera per curve to render them on top of each other. But as soon as I add other objects like a cube following the curve I would need another camera for this object so it renders in front of the curves leading to a chaos of cameras and layers.


    Many greetings and thanks in advance.
     
  2. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,295
    some random ideas,
    - z offset in custom shader https://docs.unity3d.com/Manual/SL-Offset.html (but you have so many objects, might not be ideal to have many shaders..?)
    - draw or rendertexture those lines as texture into that hexagon (if the lines are static)
     
  3. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,862
    I'd go with drawing the curves onto a texture. You only need to do this when the curves are first created or when/if they change. It's a simple and efficient solution.
     
  4. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    776
    Set z according to color?
     
  5. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,862
    Seems like OP wants to use the tiles with a perspective camera, so setting the Z value will lead to visible gaps in between curves (unless viewed trough an orthographic projection), he mentions this is not good enough for him.
     
  6. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    Disable depth test and render with particular order.
     
  7. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,862
    Wouldn't that only work if no objects occluding the tile are drawn before the curves?
     
  8. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    Objects occluding the tiles must be drawn after curves.
    You render background (gray hexagons) first.
    Than you render strips with depth test off.
    Thank you render everything else.
     
  9. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,862
    Yep, should work fine in most cases.

    Unless the curves end up having an alpha-blended material or transparency-based antialias. In that case, drawing everything else after the curves is not feasible since blending forces the curves to be rendered after all opaque objects.
     
  10. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    But you should be able to set order of drawing for transparent materials also.
    It's not like you cannot change default order, right ?
     
  11. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,295
    could also test Decals or (old) Projector.
     
    koirat likes this.
  12. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,862
    You're right, something like this should work:
    Opaque tiles -> transparent curves (ztest disabled) -> all other opaque objects -> all other transparent objects.

    Now if tiles can occlude each other, then you need to interleave drawing each tile and its curves immediately after it, sorted by tile distance to camera. It's a bit painful but I suppose can be done.

    Still prefer the render to texture approach myself, though. I feel it's a bit more robust w.r.t these kind of special cases.
     
  13. i9fasc7

    i9fasc7

    Joined:
    Jun 7, 2018
    Posts:
    74
    Sorry I did not check in on this thread during the last days.
    And thank you all for the great input. I got some new stuff to try now.
    I have not used render textures before but because the curves are static, this is an approach I will definetly look into.
    I only create the curves as meshes because I did not want to create textures for every possible curve pattern there is. For 3 curves per hexagon I think there were only like 5 patterns but add more curves and the number explodes.
     
  14. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,862
    Note it might be worth investing time in writing a custom tool that creates the textures for you: as input it takes the amount of points in each side of the tile, then it draws all possible connectivity combinations as curve meshes onto a RenderTexture and outputs the resulting textures in a folder for you.

    This way if you need to create hundreds of them or need to re-generate them often (to try various visual styles, for instance) it won't be a PITA.