Search Unity

Resolved Shader (Graph) Per Triangle Colour on a mesh with shared vertices

Discussion in 'Shaders' started by willnnotdan, Aug 2, 2021.

  1. willnnotdan

    willnnotdan

    Joined:
    Feb 24, 2020
    Posts:
    7
    Hi,
    I have been stuck with a problem for a while. I am generating meshes on the fly for certain items of my game. In order to get distinct colours per face previously Ive had each triangle have a unique set of vertices. But because Im doing this quite a bit I was worried about the performance impact of this and wanted to try and share the vertices whilst maintaining the flat look.

    For the normals I can use flat shading no problem and it gives the flat look from before. However the colours and other UV properties are now wrong (where there was once 3 vertices with 3 colours and sets of UVs there is now 1 vertice) which led me to try the per triangle approach.

    I found a few references to SV_PrimitiveID that seemed to give me what I wanted though it seems there is no way to access this in Shader Graph (which is a shame as I already have quite a complex shader graph that I would rather not convert over to a normal shader). I tried to check the generated code and I wasnt sure where I would add the SV_PrimitiveID in order to access it anyway because the file was 40k+ lines and there was no frag () method. I also tried (using URP on unity 2021.2.0b5 beta) this shader https://forum.unity.com/threads/per-triangle-color-based-on-random-seed.498748/#post-3243669 but it just gives the purple error shader without anything in the console.

    I then wondered if there was anyway to work out the triangle ID using the new custom interpolation nodes (set each vertex to some coordiante system which interpolates to unique values on each triangle).

    My final aim was then to set data in a texture 3d to be read back using the triangle ID to set colour and smoothness etc.

    I am sorry for the long post but wanted to try and include as much detail as possible. Am I barking up the wrong tree? Is this possible (ideally in shader graph)? Am I actually saving much performance by using shared vertices?

    Alternatively a method to pass information from the vertex shader to the frag non interpolated would also be helpful.

    Thanks in advance for any help
     
    Last edited: Aug 2, 2021
    gnoxii likes this.
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The short version is ... no, there's no way to do per-triangle properties using Shader Graph. The only solution is to use a pre-faceted mesh with 3 unique vertices per triangle.

    The long version is still no.
    Custom vertex interpolators could have been a solution if they supported interpolation modifiers or integers. Using a
    nointerpolation
    modifier or integer interpolator would mean that the color (or any other value) would be gotten from that triangle's invoking vertex, effectively getting you a flat color for the entire triangle. Since itself doesn't support integers it's not a big surprise they don't support that for custom vertex interpolators. Not supporting interpolation modifiers is also unfortunate, but they're still fairly esoteric so it's entirely possible they just forgot they existed. Unity's BIRP Surface Shaders never supported those either, and support for interpolation modifiers in different graphics APIs isn't universal or consistent either, so that might have also colored their view on them. There's also the issue that multiple triangles can use the same invoking vertex, and which vertex is considered the "invoking" one changes from API to API. Some it's the first vertex, some it's the last, and I think this can even change per GPU! So it doesn't offer a lot of control and different devices can appear different.

    The other solution would be g̸e̵o̷m̴e̸t̷r̵y̸ ̷s̷h̴a̶d̷e̷r̷s̵ ... uh, that's weird. Let me try that again. G̴̢͓̗̞̍e̸̹̗̺͊̆͂̉o̷̰̒̀̃m̸̨̜̘̉̐͒e̷̺̭͋̆͗̀t̵͇̀͗r̴̖͎̜̳̅ỳ̷̦͉ ̵̼͉̈́s̷̤̓͛͊͊h̵͍̯̦̝͋̓̕̚a̵̮̠̒̀d̶̘̠͇̱̽̽̈̇e̸̘̟͈̘͛̍͠r̷̥͛̏̋́s̸̯͝. Nope, that's just getting worse. Anyway, Shader Graph doesn't support those either, and since some newer graphics APIs are actively removing support for them, I would not expect Unity to ever add it.
     
  3. willnnotdan

    willnnotdan

    Joined:
    Feb 24, 2020
    Posts:
    7
    Thank you very much - I did consider geometry shaders until I realised that my own system didnt support them!

    I'll just go with the extra vertices for now, if it proves to be a major issue I will rewrite the shader graph as a normal shader.

    Thanks again for the clear and concise answer - have a good day