Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Vertex program 'vert': unknown input semantics TEXCOORD/8

Discussion in 'Shaders' started by tmcthee, Feb 24, 2020.

  1. tmcthee


    Mar 8, 2013
    I'm getting this error
    Vertex program 'vert': unknown input semantics TEXCOORD/8

    So I assume I've hit the interpolator limit described here
    "Interpolator count limits
    There are limits to how many interpolator variables can be used in total to pass the information from the vertex into the fragment shader. The limit depends on the platform and GPU, and the general guidelines are:

    • Up to 8 interpolators: OpenGL ES 2.0 (iOS/Android), Direct3D 11 9.x level (Windows Phone) and Direct3 9 shader model 2.0 (old PCs). Since the interpolator count is limited, but each interpolator can be a 4-component vector, some shaders pack things together to stay within limits. For example, two texture coordinates can be passed in one float4 variable (.xy for one coordinate, .zw for the second coordinate).
    • Up to 10 interpolators: Direct3D 9 shader model 3.0 (#pragma target 3.0).
    • Up to 16 interpolators: OpenGL ES 3.0 (iOS/Android), Metal (iOS).
    • Up to 32 interpolators: Direct3D 10 shader model 4.0 (#pragma target 4.0).
    Regardless of your particular target hardware, it is generally a good idea to use as few interpolators as possible for performance reasons."

    I've found a post written a while ago, that seems to suggest you can get around this. But I'm not quite sure what he means.

    "If you need different modified versions of your UV coordinates, you can input them as a single uv set (TEXCOORD) and output to different variables the modified versions, and pass them to fragment shader. This probably will cease the need for so many input TEXCOORDs."

    How can I output variables from the vert shader without them being defined in the v2f struct?
    (if that's actually what the responder meant)
  2. bgolus


    Dec 7, 2012
    An interpolator is the semantics passed from the vertex shader to the fragment shader. That error is saying the vertex input is an unknown semantic, which is not an interpolator.

    That's the per vertex mesh data being read by the vertex shader, which isn't limited by the interpolator count for each platform, but is limited by Unity's mesh format. For older versions of Unity, that was limited to a position, vertex color, normal, tangent, and 4 float2 UVs. Since Unity 5.2 it's been 4 float4 UVs, and since Unity 2018.2 it's been 8 float4 UVs. That translates to:
    Code (csharp):
    1. struct appdata {
    2.     float4 vertex    : POSITION;
    3.     fixed4 color     : COLOR;
    4.     float3 normal    : NORMAL;
    5.     float4 tangent   : TANGENT;
    6.     float4 texcoord0 : TEXCOORD0; // available as float4 since 5.2
    7.     float4 texcoord1 : TEXCOORD1;
    8.     float4 texcoord2 : TEXCOORD2;
    9.     float4 texcoord3 : TEXCOORD3;
    10.     float4 texcoord4 : TEXCOORD4; // available since 2018.2
    11.     float4 texcoord5 : TEXCOORD5;
    12.     float4 texcoord6 : TEXCOORD6;
    13.     float4 texcoord7 : TEXCOORD7;
    14. };
    So that's the maximum data you can set on a mesh on import or from c# and read in a vertex shader. But again, that's just the vertex shader input, which has no affect on interpolators which are the vertex shader output.

    To me it sounds like you're either reusing the
    struct for both the vertex shader input and output, or your modifying both the
    struct and
    struct when adding interpolators. Neither of these are things you should be doing. They are separate things that should not be conflated, even though they both use semantics.

    Personally I use the predefined
    structs (defined in the UnityCG.cginc file) for 99% of my own shaders. Those look like this:
    Code (CSharp):
    1. struct appdata_full {
    2.     float4 vertex : POSITION;
    3.     float4 tangent : TANGENT;
    4.     float3 normal : NORMAL;
    5.     float4 texcoord : TEXCOORD0;
    6.     float4 texcoord1 : TEXCOORD1;
    7.     float4 texcoord2 : TEXCOORD2;
    8.     float4 texcoord3 : TEXCOORD3;
    9.     fixed4 color : COLOR;
    11. };
    13. // Helpers used in image effects. Most image effects use the same
    14. // minimal vertex shader (vert_img).
    16. struct appdata_img
    17. {
    18.     float4 vertex : POSITION;
    19.     half2 texcoord : TEXCOORD0;
    21. };
    It's rare you use meshes with more than 4 UVs, and the shader compiler will optimize away any vertex inputs that go unused. BTW, the
    macro I didn't include with my big list above as it's not technically part of vertex data, but rather an additional vertex shader input the GPU generates. Specifically
    , but that's getting off topic a bit.

    The TLDR version is your shader should look like this:
    Code (csharp):
    1. struct v2f {
    2.     float4 pos : SV_Position;
    3.     float2 uv : TEXCOORD0;
    4.     float3 something : TEXCOORD1;
    5.     float3 fred : TEXCOORD2;
    6.     float3 unicorns : TEXCOORD3;
    7.     // etc.
    8.     float4 supercalifragilisticexpialidocious : TEXCOORD14;
    9. };
    11. v2f vert(appdata_full v) {
    12.     v2f o;
    13.     o.pos = UnityObjectToClipPos(v.vertex);
    14.     o.uv = TRANSFORM_TEX(v.texcoord.xy, _MainTex);
    15.     o.something = // etc
    16.     // ...
    17.     o.supercalifragilisticexpialidocious = quiteAttrocious;
    18.     return o;
    19. };
  3. tmcthee


    Mar 8, 2013
    Thanks again Bgolus, that's clarified a lot for me.