Unity Shader基礎(chǔ)練習(三)CG入門

區(qū)分Unity 中3大Shader

沒有嵌套CG語言,也就是代碼段中沒有CGPROGARAM和ENDCG關(guān)鍵字的粟誓,就是固定功能著色器。
嵌套了CG語言,代碼段中有surf函數(shù)的蒜埋,就是表面著色器。
嵌套了CG語言毅臊,代碼段中有#pragma vertex name和 #pragma fragment frag聲明的理茎,就是頂點著色器&片段著色器黑界。
從這里開始不加;會報錯

Shader "Sbin/vf" {
    
    SubShader {
        pass{
        //CG代碼寫到限定范圍內(nèi)
        CGPROGRAM
        //CG類似類的聲明 都要小寫不然不報錯也不顯示
        #pragma vertex vert  
        #pragma fragment frag
        //頂點    //變量 傳入 2階向量 //傳出一個四階 pos
        void vert(in float2 objPos:POSITION,out float4 pos:POSITION)
        {
          pos=float4(objPos,0,1);
        }
        //COLOR=COLOR0
        void frag(out float4 col:COLOR0)
        {
          col=float4(1,0,0,1);
        }
        ENDCG
        }
    }

}
image.png

然后成了這樣 說是以后再解釋 我的Game視圖什么也看不見 視屏卻有


image.png
Shader "Sbin/vf" {
    
    SubShader {
        pass{
        //CG代碼寫到限定范圍內(nèi)
        CGPROGRAM
        //CG類似類的聲明 都要小寫不然不報錯也不顯示
        #pragma vertex vert  
        #pragma fragment frag
        //頂點    //變量 傳入 2階向量 //傳出一個四階 pos
        void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
        {
          pos=float4(objPos,0,1);
          col=float4(0,0,1,1);//也可以這樣賦值 不過frag里的col賦值會覆蓋這個
        }
        //COLOR=COLOR0 片段著色器
        void frag(inout float4 col:COLOR)
        {       
          col=float4(0,1,0,1);
        }
        ENDCG
        }
    }

}

還是顯示不出來 運行會報錯但是不知道哪里錯了
找到原因了


image.png

把matrail的渲染隊列調(diào)為transparent


image.png

然后就Game視圖有圖了 但是還是運行會報
image.png

image.png

右邊顯示沒有錯誤 很神奇
這是人家視頻的效果


image.png
Shader "Sbin/vf" {

    SubShader{
        pass {
        //CG代碼寫到限定范圍內(nèi)
        CGPROGRAM
            //CG類似類的聲明 都要小寫不然不報錯也不顯示
            #pragma vertex vert  
            #pragma fragment frag
            //頂點    //變量 傳入 2階向量 //傳出一個四階 pos
            void vert(in float2 objPos:POSITION,out float4 pos : POSITION,out float4 col : COLOR)
            {
              pos = float4(objPos,0,1);
              col = pos;//也可以這樣賦值 不過frag里的col賦值會覆蓋這個
            }
        //COLOR=COLOR0 片段著色器
        void frag(inout float4 col:COLOR)
        {
          //col = float4(0,1,0,1);
        }
        ENDCG
        }
    }

}
image.png

我換了2018版本的就好了但是圖是反過來的

CG基本數(shù)據(jù)類型

float half fixed bool int sampler*
頂點和片段profile是某硬件可支持的預算的一種特性

Shader "Sbin/vf" {

    SubShader{
        pass {
        //CG代碼寫到限定范圍內(nèi)
        CGPROGRAM
            //CG類似類的聲明 都要小寫不然不報錯也不顯示
            #pragma vertex vert  
            #pragma fragment frag
            //頂點    //變量 傳入 2階向量 //傳出一個四階 pos
            void vert(in float2 objPos:POSITION,out float4 pos : POSITION,out float4 col : COLOR)
            {
              pos = float4(objPos,0,1);
              col = pos;//也可以這樣賦值 不過frag里的col賦值會覆蓋這個
            }
        //COLOR=COLOR0 片段著色器
        void frag(inout float4 col:COLOR)
        {
          //col = float4(0,1,0,1);
          
          fixed r=-0.5;
          fixed g=-0.5;
          fixed b=0;
          fixed a=0;
          //CG里的構(gòu)造器 
          col=float4(r,g,b,a);
          //CG的基本類型 根據(jù)不同精度定義的數(shù)據(jù)類型 CG不含有指針
          //fixed1=fixed 描述的是9位整數(shù)被規(guī)格化到-1到1 就是2的8次方 256跟顏色的最大值對應(yīng)
          //fixed2=fixed(1,0);
          //float可以變?yōu)閒loat2 float3 float4 沒有五階
          //half half2 half3 half4
          //fixed fixed2 fixed3 fixed4
        }
        ENDCG
        }
    }

}
![image.png](https://upload-images.jianshu.io/upload_images/15146729-5666734f1a3c801e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
官方已經(jīng)到了5.0 DX11
Shader "Sbin/vf" {

    SubShader{
        pass {
        //CG代碼寫到限定范圍內(nèi)
        CGPROGRAM
            #include "UnityCG.cginc"
        //CG類似類的聲明 都要小寫不然不報錯也不顯示
            #pragma vertex vert  
            #pragma fragment frag
            //定義宏
            #define MACROFL FL4(fl4.ab,fl3.zy);
            typedef float4 FL4;//聲明別名
           //結(jié)構(gòu)體  2018新版本不能為空
            struct v2f{
                  float4 pos:POSITION;
                  float2 uv:TEXCOORD0;
              };
            //頂點    //變量 傳入 2階向量 //傳出一個四階 pos
        void vert(in float2 objPos:POSITION,out float4 pos : POSITION,out float4 col : COLOR)
        {
              pos = float4(objPos,0,1);
              col = pos;//也可以這樣賦值 不過frag里的col賦值會覆蓋這個

        }
        //COLOR=COLOR0 片段著色器
        void frag(inout float4 col:COLOR)
        {
          //col = float4(0,1,0,1);
          
          fixed r=-0.5;
          fixed g=-0.5;
          fixed b=0;
          fixed a=0;
          //CG里的構(gòu)造器 
          col=float4(r,g,b,a);

          bool bl=false;
          col=bl?col:fixed4(0,1,0,1);//true是黑 false是綠

          //int 一般會被當作float使用
          //描述是幾維向量
          float2 fl2=float2(1,0);
          float3 fl3=float3(1,0,1);
          float4 fl4=float4(1,1,0,1);
          
          //Swizzle操作 
          //float4 fl=float4(fl2,0,1);//紅色
          //float4 fl=float4(fl2.xy,0,1);//xyzw 或者 rgba按照一定順序去取可以截取這個值
          //float4 fl=float4(fl4.wzyx);//紫色
           //float4 fl=float4(fl4.ab,fl3.zy);//紫色
            //宏的使用
           FL4 fl=MACROFL //紫色
           col=fl;

          //CG的基本類型 根據(jù)不同精度定義的數(shù)據(jù)類型 CG不含有指針
          //fixed1=fixed 描述的是9位整數(shù)被規(guī)格化到-1到1 就是2的8次方 256跟顏色的最大值對應(yīng)
          //fixed2=fixed(1,0);
          //float可以變?yōu)閒loat2 float3 float4 沒有五階
          //half half2 half3 half4
          //fixed fixed2 fixed3 fixed4
           //2行4列的矩陣 通常用4x4不會報錯但是會黃色警告
          // float2x4 M2x4={1,0,0,1,0,1,0,1};//便于閱讀也可以{(1,0,0,1),(0,1,0,1)}
             float4x4 M2x4={1,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0};
           col=M2x4[0];//取矩陣第一行 紅色     
           col=M2x4[1];//取矩陣第二行 綠色
           //數(shù)組 
           float arr[4]={1,0.5,0.5,1};//橙紅色
           col=float4(arr[0],arr[1],arr[2],arr[3]);
           //結(jié)構(gòu)體賦值 改值操作
           v2f o;
           o.pos=fl4;
           o.uv=fl2;
        }
        ENDCG
        }
    }

}

CG的條件語句

if..else
while
Do...while
for
switch...case(有用但是最好別用皂林,沒有良好的支持朗鸠,容易亂)

我這邊試的也有錯

Shader "Sbin/vf1" {
  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 && pos.y<0)
    {
      col=float4(1,0,0,1);
    }
    else if(pos.x<0)
    {
      col=float4(0,1,0,1);
    }
    else if(pos.y>0)
    {
      col=float4(1,1,0,1);
    }
    else
    {
      col=float4(0,0,1,1);
    }
    //col=pos;
   }

    void frag(inout float4 col:COLOR)
    {
      //最好別用有一定問題 用if else代替
      // int i=0;
      // switch(i)
      // {
      //   case 0:
      //   col=float4(1,0,0,1);
      //   break;
      //   case 1:
      //   col=float4(0,1,0,1);
      //   break;
      //   case 2:
      //   col=float4(0,0,1,1);
      //   break;
      // }
    }
    ENDCG
  }
  }
  
}
image.png

老師是這樣的我的進不來
之后的還可以

Shader "Sbin/vf1" {
  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);
    col=pos;
   }

    void frag(inout float4 col:COLOR)
    {
    //測試while
     int i=0;
     while(i<10)
     {
       i++;
     }
     if(i==10)
     {
     col=float4(0,0,0,1);
     }
     //看下do while
     i=0;
     do{
     i++;
     }
     while(i<10);
     if(i=10)
      col=float4(1,1,1,1);

      //for 循環(huán)有上限 老師的是1023 我的直接報黃說被迫執(zhí)行一次循環(huán)
      i=0;
      for(i=0;i<10;i++)
      {
       if(i=10)
       col=float4(0.5f,0.5f,0,1);
      }
      

    }
    ENDCG
  }
  }
  
}

這個也動不了 之后把上面提示的錯誤信息刪掉就好了

// Upgrade NOTE: excluded shader from DX11, OpenGL ES 2.0 because it uses unsized arrays
#pragma exclude_renderers d3d11 gles
Shader "Sbin/vf1" {
  SubShader {
    pass{   
    CGPROGRAM
// Upgrade NOTE: excluded shader from DX11, OpenGL ES 2.0 because it uses unsized arrays
#pragma exclude_renderers d3d11 gles
    #pragma vertex vert
    #pragma fragment frag
     void Func(out float4 c);
   float Func2(float arr[2])
   {
     float sum=0;
     for (int i=0;i<arr.Length;i++)
     {
       sum+=arr[i];
     }
     return sum;
   }
   
   void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
   {
    pos=float4(objPos,0,1);
    col=pos;
   }
 
    void frag(inout float4 col:COLOR)
    {
        //Func(col);
      //維度必須相同傳遞 沒有維度不行 
      float arr[]={0.5,0.5};
      //我的Func2掛掉了 說我的GPU不支持明暗編輯器
      col.x= Func2(arr);
    }

      //函數(shù)必須在調(diào)用之前 或者在之前聲明
   void Func(out float4 c)
     {
     //CG參數(shù)以值拷貝進行傳遞
     c=float4(0,1,0,1);
     }
    ENDCG
  }
}
  
}

自定義函數(shù)

這樣每次在頭聲明函數(shù)很麻煩
創(chuàng)建一個cginc的文件


image.png

里面放自己的函數(shù)

   //函數(shù)必須在調(diào)用之前 或者在之前聲明
  void Func(out float4 c)
    {
    //CG參數(shù)以值拷貝進行傳遞
    c=float4(0,1,0,1);
    }
  float Func2(float arr[2])
  {
    float sum=0;
    for (int i=0;i<arr.Length;i++)
    {
      sum+=arr[i];
    }
    return sum;
  }
Shader "Sbin/vf1" {
SubShader {
  pass{   
  CGPROGRAM
  #pragma vertex vert
#pragma fragment frag
  //自定義函數(shù)
 #include "sbin.cginc"
 
 void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
 {
  pos=float4(objPos,0,1);
  col=pos;
 }

  void frag(inout float4 col:COLOR)
  {
      Func(col);
    //維度必須相同傳遞 沒有維度不行 
    float arr[2]={0.5,0.5};
    //我的Func2掛掉了 說我的GPU不支持明暗編輯器 把上面自動生成的提示刪了就好了
    col.x= Func2(arr);
  }

  
  ENDCG
}
}

}
image.png

是黃色
當Shader和.cginc在同一目錄情況下可以直接名字引用
如果放在不同文件夾 應(yīng)該是安路徑找 但是我的就可以直接用 回報黃 然后多試了幾下還是會報錯 第一個是我放的文件夾 建議這么寫

include "Cginc/sbin.cginc"

找到unity安裝包路徑 這個就是unity自帶的CG庫 我們可以調(diào)用 為我們節(jié)省很多時間
Editor/Data/CGIncludes(MAC下是Content/CGIncludes)

Unity函數(shù)

這個文庫很全
https://wenku.baidu.com/view/3a9db318fad6195f312ba675.html
常用的lerp(a,b,f)是個差值

image.png

感覺像是個max()min()結(jié)合體
image.png

還有這個sin cos結(jié)合函數(shù)
image.png

就是把矩陣行變成列
image.png

這個模 就是向量v開平方相加除根號
image.png

為什么這么簡單的要封裝起來,因為他們的算是優(yōu)化速度最快的础倍,自己寫的話不一定有他們快 就跟自己Json寫的序列化反序列化 不如人家谷歌那群人寫的Protobuf得快
這個是Shader源碼
https://github.com/1004019267/ShaderTest/tree/master

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末烛占,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沟启,更是在濱河造成了極大的恐慌忆家,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件德迹,死亡現(xiàn)場離奇詭異芽卿,居然都是意外死亡,警方通過查閱死者的電腦和手機胳搞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門卸例,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人肌毅,你說我怎么就攤上這事筷转。” “怎么了悬而?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵呜舒,是天一觀的道長。 經(jīng)常有香客問我笨奠,道長袭蝗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任艰躺,我火速辦了婚禮呻袭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘腺兴。我一直安慰自己左电,他們只是感情好,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布页响。 她就那樣靜靜地躺著篓足,像睡著了一般。 火紅的嫁衣襯著肌膚如雪闰蚕。 梳的紋絲不亂的頭發(fā)上栈拖,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天,我揣著相機與錄音没陡,去河邊找鬼涩哟。 笑死索赏,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的贴彼。 我是一名探鬼主播潜腻,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼器仗!你這毒婦竟也來了融涣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤精钮,失蹤者是張志新(化名)和其女友劉穎威鹿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轨香,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡忽你,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了弹沽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片檀夹。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖策橘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情娜亿,我是刑警寧澤丽已,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站买决,受9級特大地震影響沛婴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜督赤,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一嘁灯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧躲舌,春花似錦丑婿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至约计,卻和暖如春诀拭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背煤蚌。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工耕挨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留细卧,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓筒占,卻偏偏與公主長得像酒甸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子赋铝,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容