Search Unity

Unity shader code reflection/introspection?

Discussion in 'General Graphics' started by naelstrof, May 7, 2020.

  1. naelstrof

    naelstrof

    Joined:
    Sep 12, 2017
    Posts:
    22
    I'm trying to write a tessellation and geometry shader for HDRP-- The biggest challenge is that each pass of the shader needs different variables interpolated.

    I ended up writing something like this, which works...
    Code (CSharp):
    1. [domain("tri")]
    2. AttributesMesh domain(TessellationFactors factors, OutputPatch<AttributesMesh, 3> patch, float3 barycentricCoordinates : SV_DomainLocation) {
    3.     AttributesMesh v = (AttributesMesh)0;
    4.  
    5.     #define TESS_INTERPOLATE(fieldName) v.fieldName = \
    6.         patch[0].fieldName * barycentricCoordinates.x + \
    7.         patch[1].fieldName * barycentricCoordinates.y + \
    8.         patch[2].fieldName * barycentricCoordinates.z;
    9.  
    10.     #if defined(GBUFFER_PASS)
    11.         TESS_INTERPOLATE(positionOS)
    12.         TESS_INTERPOLATE(normalOS)
    13.         TESS_INTERPOLATE(tangentOS)
    14.         TESS_INTERPOLATE(uv1)
    15.         TESS_INTERPOLATE(uv2)
    16.         TESS_INTERPOLATE(ase_texcoord)
    17.         TESS_INTERPOLATE(ase_color)
    18.     #elif defined(DEPTH_ONLY_PASS)
    19.         TESS_INTERPOLATE(positionOS)
    20.         TESS_INTERPOLATE(normalOS)
    21.         TESS_INTERPOLATE(tangentOS)
    22.         TESS_INTERPOLATE(ase_texcoord)
    23.         TESS_INTERPOLATE(ase_color)
    24.     #elif defined(FORWARD_PASS)
    25.         TESS_INTERPOLATE(positionOS)
    26.         TESS_INTERPOLATE(normalOS)
    27.         TESS_INTERPOLATE(tangentOS)
    28.         TESS_INTERPOLATE(uv1)
    29.         TESS_INTERPOLATE(uv2)
    30.         TESS_INTERPOLATE(ase_texcoord)
    31.         TESS_INTERPOLATE(ase_color)
    32.         #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
    33.             TESS_INTERPOLATE(previousPositionOS)
    34.             #if defined (_ADD_PRECOMPUTED_VELOCITY)
    35.                 TESS_INTERPOLATE(precomputedVelocity)
    36.             #endif
    37.         #endif
    38.     #elif defined(SHADOW_PASS)
    39.         TESS_INTERPOLATE(positionOS)
    40.         TESS_INTERPOLATE(normalOS)
    41.         TESS_INTERPOLATE(tangentOS)
    42.         TESS_INTERPOLATE(ase_texcoord)
    43.         TESS_INTERPOLATE(ase_color)
    44.     #elif defined(MOTION_VECTOR_PASS)
    45.         TESS_INTERPOLATE(positionOS)
    46.         TESS_INTERPOLATE(normalOS)
    47.         TESS_INTERPOLATE(tangentOS)
    48.         TESS_INTERPOLATE(ase_color)
    49.         TESS_INTERPOLATE(ase_texcoord)
    50.         TESS_INTERPOLATE(previousPositionOS)
    51.         #if defined (_ADD_PRECOMPUTED_VELOCITY)
    52.             TESS_INTERPOLATE(precomputedVelocity)
    53.         #endif
    54.     #endif
    55.  
    56.     return v;
    57. }
    But it's horribly tedious to write/adjust... I basically manually define within the shader which variables exist and include this domain function from another file.

    Is there a way to just iterate through all variables within a struct and do TESS_INTERPOLATE() on each?
    Something like
    Code (CSharp):
    1.  
    2.     foreach(var property in AttributesMesh) {
    3.         TESS_INTERPOLATE(property);
    4.     }
    5.  
    would be amazing, though I'm pretty sure I'm coming at the problem wrong. For Amplify shader creations, there's no way to know which fields will exist or not, is there a dynamic way to just interpolate all the contents of a struct?