cg輸入輸出匹配規則

最近論壇看到有人提出這樣的問題:

Shader "Unlit/testinout"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
            {
              pos=float4(objPos,0,1);
              if(pos.x<0){
                col=float4(1,0,0,1);
              }
              else
              {
                col=float4(0,1,0,1);
              }
            }
            void frag(inout float4 col:COLOR)  //輸出的並不是col的顏色?????
            {
            }
            ENDCG
        }
    }
}

這個問題其實是語義綁定的規則,上面的片段着色器其實輸出的是pos這個變量,並不是col。

注意:語義綁定是頂點和片段之間的橋樑,是一對一的關係,是根據類型進行匹配的,不是根據名稱去匹配的。

正確的寫法有如下幾種

方法一:增加輸入參數

    Shader "a958832776/testinout"
    {
        SubShader
        {
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
                {
                  pos=float4(objPos,0,1);
                  if(pos.x<0){
                    col=float4(1,0,0,1);
                  }
                  else
                  {
                    col=float4(0,1,0,1);
                  }
                }
                void frag(in float4 pos:POSITION,inout float4 co:COLOR)  //注意需要帶上頂點輸出的POSITION語義
                {
                }
                ENDCG
            }
        }
    }

方法二:直接返回值

 Shader "a958832776/testinout"
    {
        SubShader
        {
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                 //直接返回顏色
                float4 vert(in float2 objPos:POSITION,out float4 pos:POSITION):COLOR
                {
                     float4 col=float4(0,0,0,0);
                      pos=float4(objPos,0,1);
                      if(pos.x<0){
                        col=float4(1,0,0,1);
                      }
                      else
                      {
                        col=float4(0,1,0,1);
                      }
                      return col;
                }
                void frag(inout float4 co:COLOR)
                {
                }
                ENDCG
            }
        }
    }

方法三:定義結構體

    Shader "a958832776/testinout"
    {
        SubShader
        {
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag

                 struct out_data{
                   float4 pos:POSITION;
                   float4 col:COLOR;
                 };

              out_data vert(float2 objPos:POSITION)
                {
                      out_data data;
                      data.pos=float4(objPos,0,1);
                      if(data.pos.x<0){
                        data.col=float4(1,0,0,1);
                      }
                      else
                      {
                        data.col=float4(0,1,0,1);
                      }
                      return data;
                }
                float4 frag(out_data d):COLOR
                {
                  return d.col;
                }
                ENDCG
            }
        }
    }

推薦使用方法三,這樣結構更清晰明瞭,也不會出錯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章