Search Unity

How variable is passed at Unity Shader ?

Discussion in 'Shaders' started by Isaac_1993, May 1, 2020.

  1. Isaac_1993

    Isaac_1993

    Joined:
    May 1, 2020
    Posts:
    7
    Hi
    I got a very beginning question, here is my code:

    Code (CSharp):
    1. Pass
    2. {
    3.     Tags {"LightMode"="ForwardBase"}
    4.     CGPROGRAM
    5.         #pragma vertex vert
    6.         #pragma fragment frag
    7.         #include "Lighting.cginc"
    8.         fixed4 _Diffuse;
    9.         fixed4 _Specular;
    10.         fixed4 _Gloss;
    11.         struct a2v{
    12.             float4 vertex :  POSITION;
    13.             float3 normal : NORMAL;
    14.             };
    15.         struct v2f{
    16.             float4 pos : SV_POSITION;
    17.             fixed3 color : COLOR;
    18.             };
    19.         v2f vert (a2v v) {
    20.             v2f o;
    21.             o.pos = UnityObjectToClipPos(v.vertex);
    22.             o.color = (1.0,1.0,1.0);
    23.             return o;
    24.           }
    25.  
    26.         fixed4 frag (v2f i) : SV_Target
    27.         {
    28.         return fixed4(i.color,1.0);
    29.         }
    30.  
    31. ENDCG
    I initialized a struct 'v2f' at the vert process, and you can see I directly using the result of the variable at the 'frag' process. My question is how the Unity knows the variable 'i' is the variable 'o' that I have calculated at the vert process? What would happen if I initialize more than one v2f struct at the vert process? Is the 'struct v2f' kind of like the global variable, the vert process modified it first then the frag process can read it?
     
  2. drcrck

    drcrck

    Joined:
    May 23, 2017
    Posts:
    328
    see "return o;" line 23
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The simple version is vertex shader outputs a v2f, and the fragment shader's input is a v2f.

    Except those aren't really the same thing. More over, they don't even need to be the same struct! The struct is just an easy way to ensure both have the same kinds of data.

    What actually matters is the semantics being used. Those are the usually all in caps bits of text after the semicolon (
    :
    ) after each variable and the fragment function. Those are essentially data channels that the shader can specify to send data through to get to the different shader stages. The structs are just an easier way to list them out.

    Code (csharp):
    1. float4 vert (float4 vertex : POSITION, float2 inUV : TEXCOORD0, out float2 outUV : TEXCOORD0) : SV_POSITION
    2. {
    3.   outUV = inUV;
    4.   return UnityObjectToClipPos(vertex);
    5. }
    6.  
    7. void frag(float2 texcoord : TEXCOORD0, out half4 color : SV_Target)
    8. {
    9.   color = Tex2D(_MyTex, texcoord);
    10. }
    That code totally works too with no structs. It's way more confusing, but it does still work. Because the only thing that actually matters is the semantics and if a value is the input or output.

    Actually, I wonder if
    inout float2 uv : TEXCOORD0
    would work...
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Also, understand the output of the vertex shader is not the same as the input for the fragment shader. The value output from the vertex shader is for one vertex. The input for the fragment shader is the barycentric interpolated value of all 3 vertices for the triangle that pixel is drawing.
     
  5. Isaac_1993

    Isaac_1993

    Joined:
    May 1, 2020
    Posts:
    7
    Hi
    Thank for your reply. But it still confuses me.
    Thank you a lot, this question bothered me for a while! Now I think I know what happens.