Shader unexpected token v2f error

Hello all,

I am learning how to do shader programming, and using this video as a base:

I am completely new to this, so apologies if I made a newbie mistake.

I got to the bit where I implemented the vertex and fragment functions. In the video, he is able to have an object with a texture and a colour overlayed. I, on the other hand, am getting an error;
syntax error: unexpected token ‘v2f’
Compiling Vertex program
Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING SHADER_API_DESKTOP

I have made sure all varibles are written correctly, even went as far as making a new shader in Notepad++ and saving it but my shader does not compile.

My code (there’s a bunch of comments):

Shader "MyShader/Test2"{
    // Unity uses ShaderLab, consider this the frontend
    // CG can be considered the backend
    // Properties are like public variables
    // This is just a frontend, we're not applying them to anything
    Properties{
        _MainTexture("Main Color (RGB) Test2!", 2D) = "white"{} // Internal reference name, public name (inspector), data type, initialising value (can be nothing)
        _Color("Colour", Color) = (1,1,1,1)
    }
   
    // Can have multiple SubShader to target different platforms
    SubShader{
       
        // Pass takes data and draws them on to screen, can have multiple passes; each can do something that will interate how the object is rendered onto screen
        // Each pass is a draw call, so 3 pass means 3 draw calls
        Pass{

            // The main thing that applies shading to objects
            CGPROGRAM
                // Need two functions; the Vertex and Fragment
                // Similar to C/C++, we tell CGPROGRAM function identifiers
                #pragma vertex vertexFunction
                #pragma fragment fragmentFunction
               
                //Can also include external files to use different functions
                #include "UnityCG.cginc"
               
                // first, We need to get data from the object to use
                struct appdata {
                    // We pass in the values we want, such as verticies, normals, colour, uv
                    float4 vertex : SV_POSITION; // data type to store, variable name, the type of data i'm getting
                    float2 uv : TEXCOORD0;
                };
               
                // We need an object from vertex to pass onto fragment, so we store this in a struct
                struct v2f {
                    float4 position : SV_POSITION; // SV_POSITION has to do something with working with DX platforms
                    float2 uv : TEXCOORD0;
                };

                // Take the stuff from ShaderLab and import into CG
                float4 _Color;
                sampler2D _MainTexture

                //Vertex
                //Build the object
                // Return type, function name, parameters (variable, input/output?)
                v2f vertexFunction (appdata IN) {
                    v2f OUT;
                    OUT.position = mul(UNITY_MATRIX_MVP, IN.vertex); // multiply (nvidia cg function)
                    // MVP - Model View Projection - Get the model, get the view from camera, get the projection from the camera; send this to screen
                    // Takes into account whether the camera is in perspective or orthographic
                   
                    OUT.uv = IN.uv;
                    return OUT;
                }
                   
                //Fragment
                //Colour it in
                fixed4 fragmentFunction (v2f IN) : SV_Target{
                    // Take the colour
                    float textureColor = tex2D(_MainTexture, IN.uv);

                    // Take the texture

                    return textureColor * _Color;
                }
            ENDCG
        }
    }

}

I understand that the compiler is basically saying that I am using something that is not recognised, however, I have defined “v2f” as a struct, so I am confused what I am doing wrong.

Many thanks

Nevermind, turns out I missed a semi-colon at line 43. Typical :sweat_smile:

However only seems to change the colour and the texture doesn’t seem to apply. Trying to apply the texture on to a Cube.

Line 43 should end with a semi-colon. sampler2D _MainTexture;

You got it :slight_smile:

Line 62 should also be a fixed4.

Thanks for replying, I tried changing it to a fixed4 and float4 (the guy had it set to a float4 before). After saving the changes, I removed the material and then reapplied it with the shader, but I am still getting a solid colour.

fixed vs half vs float is irrelevant on desktop platforms, they’re literally the same thing because desktop GPUs always do everything as if they’re floats regardless of the precision level requested. It does matter for mobile, but in this case either fixed or float precision should work. fixed4 exists primarily to handle color information.

However are you sure you’re looking at line 62? You’re using a singular float instead of a float4 or fixed4.

float textureColor = tex2D(_MainTexture, IN.uv);
^^^^^
fixed4 textureColor = tex2D(_MainTexture, IN.uv);

Yes, grizzly pointed that particular line out and I changed it to float4. What happens is that I get a solid colour but no texture, even though the sphere-preview shows the material having a texture, albeit distorted.

The only other issue I see is the appdata vertex variable should be POSITION and not SV_POSITION, the later should only be used for the output of the vertex shader function. However that shouldn’t cause what you’re seeing, only some compiler errors on specific platforms. Can you post your updated shader?

Sure thing, only thing that has been changed is line 62; changed from float to float4

Shader "MyShader/Test2"{
    // Unity uses ShaderLab, consider this the frontend
    // CG can be considered the backend
    // Properties are like public variables
    // This is just a frontend, we're not applying them to anything
    Properties{
        _MainTexture("Main Color (RGB) Test2!", 2D) = "white"{} // Internal reference name, public name (inspector), data type, initialising value (can be nothing)
        _Color("Colour", Color) = (1,1,1,1)
    }
   
    // Can have multiple SubShader to target different platforms
    SubShader{
       
        // Pass takes data and draws them on to screen, can have multiple passes; each can do something that will interate how the object is rendered onto screen
        // Each pass is a draw call, so 3 pass means 3 draw calls
        Pass{

            // The main thing that applies shading to objects
            CGPROGRAM
                // Need two functions; the Vertex and Fragment
                // Similar to C/C++, we tell CGPROGRAM function identifiers
                #pragma vertex vertexFunction
                #pragma fragment fragmentFunction
               
                //Can also include external files to use different functions
                #include "UnityCG.cginc"
               
                // first, We need to get data from the object to use
                struct appdata {
                    // We pass in the values we want, such as verticies, normals, colour, uv
                    float4 vertex : SV_POSITION; // data type to store, variable name, the type of data i'm getting
                    float2 uv : TEXCOORD0;
                };
               
                // We need an object from vertex to pass onto fragment, so we store this in a struct
                struct v2f {
                    float4 position : SV_POSITION; // SV_POSITION has to do something with working with DX platforms
                    float2 uv : TEXCOORD0;
                };

                // Take the stuff from ShaderLab and import into CG
                float4 _Color;
                sampler2D _MainTexture;

                //Vertex
                //Build the object
                // Return type, function name, parameters (variable, input/output?)
                v2f vertexFunction (appdata IN) {
                    v2f OUT;
                    OUT.position = mul(UNITY_MATRIX_MVP, IN.vertex); // multiply (nvidia cg function)
                    // MVP - Model View Projection - Get the model, get the view from camera, get the projection from the camera; send this to screen
                    // Takes into account whether the camera is in perspective or orthographic
                   
                    OUT.uv = IN.uv;
                    return OUT;
                }
                   
                //Fragment
                //Colour it in
                fixed4 fragmentFunction (v2f IN) : SV_Target{
                    // Take the colour
                    float4 textureColor = tex2D(_MainTexture, IN.uv);

                    // Take the texture

                    return textureColor * _Color;
                }
            ENDCG
        }
    }

}

Yes, I had originally noticed this and believed the same but having tested the revised shader it would seem Unity may or may not warn of this issue. Try removing the SV_ from the input struct, recompile, then add it back. Unity will warn the first time then completely miss it thereafter.

The inclusion of the SV_ in appdata is causing your UV’s to become corrupt. Remove the SV_ prefix and you should be good to go:

struct appdata {   
    float4 vertex : POSITION; 
    float2 uv : TEXCOORD0;
};
1 Like

That fixed it, I am guessing I was missing some package or the current version of Unity I’m using is doing something different. Thank you grizzly and bgolus