TEXCOORD1 problem?

I am trying to use uv2 on a mesh in a simple shader but I can’t get it to work, just seems I have 0,0 in all the uv2 but checking the mesh data that is not the case, can anyone help in what I am doing wrong in this very simple shader?

Shader "Custom/Text UV2"
{
    Properties
    {
        _Color("Color", Color) = (1,1,1,1)
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _Texture2("Texture 2 (RGB)", 2D) = "white" {}
        _Amount("Amount", 2D) = "white" {}
        _Glossiness("Smoothness", Range(0,1)) = 0.5
        _Metallic("Metallic", Range(0,1)) = 0.0
    }
        SubShader
        {
            Tags { "RenderType" = "Opaque" }
            LOD 200

            CGPROGRAM
            // Physically based Standard lighting model, and enable shadows on all light types
            #pragma surface surf Standard fullforwardshadows

            // Use shader model 3.0 target, to get nicer looking lighting
            #pragma target 3.0

            sampler2D _MainTex;
            sampler2D _Texture2;
            sampler2D _Amount;

            struct Input
            {
                float2 uv_MainTex : TEXCOORD0;
                float2 uv2_Tex : TEXCOORD1;
            };

            half _Glossiness;
            half _Metallic;
            fixed4 _Color;

            // #pragma instancing_options assumeuniformscaling
            UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
            UNITY_INSTANCING_BUFFER_END(Props)

            void surf(Input IN, inout SurfaceOutputStandard o)
            {
                fixed4 c = tex2D(_Texture2, IN.uv2_Tex) * _Color;
                o.Albedo = c.rgb;
                o.Metallic = _Metallic;
                o.Smoothness = _Glossiness;
                o.Alpha = c.a;
            }
            ENDCG
        }
        FallBack "Diffuse"
}

I believe it’ll work if you change line 31 to float2 uv2_Texture2; or float2 uv2_MainTex;. Trying to find a proper source on this but I believe the standard shader input expects the name of the uv channel to match one of the sampler2Ds.

EDIT: Source is here. “Texture coordinates must be named “uv” followed by texture name (or start it with “uv2” to use second texture coordinate set).”

If I change it to uv2_MainTex : TEXCOORD1 the shader gives compile errors:
Shader error in ‘Custom/Road’: redefinition of ‘_MainTex_ST’ at line 76 (on d3d11)

Down near the bottom, under the heading “Surface Shader Input Structure”

EDIT: You don’t need the TEXCOORD1, just declare it as uv2_MainTex or uv2_Texture2.

Thanks again, I did the change of name to uv2.Texture2 and removed the TEXCOORD and it compiles, but now just uses uv for everything and not uv2.

Started again and seems it working now, very odd naming convention I thought the TEXCOORDx was supposed to deal with all this.

Those are shader semantics, and are used for getting data from the base mesh and passing data between the vertex and fragment shader passes. The problem here is Surface Shaders are vertex fragment shader generators. The Input struct is a list of values that it’s parsing to figure out what values it needs to get from the base mesh in the vertex shader, and pass on to the fragment shader. The Input struct itself is constructed in the fragment shader from data from a different generated struct that actually uses those semantics, so the ones set on the Input struct are ignored. Unity could parse the semantics in that struct, but unfortunately the only semantic it does look for is COLOR. UVs are much more rigidly limited to the uv_TextureName and uv2_TextureName setup, where the texture name must be exactly the same name as one in the shader’s properties, and will always apply that texture’s scale and offset. You can pass the unmodified UVs using a custom Input value not named “uv_” and using a custom vertex function to fill in the data.

2 Likes

Thanks for the help, would be nice if that was all made a bit clearer on the Unity shader pages, but working now so again thanks all.

1 Like