Unity Shader 學習筆記—圖形基礎/CG語法

圖形編程歷史

渲染流水線

目前最新的可編程圖形硬件支持功能:

  • 支持頂點和片段的可編程能力
  • 支持IEEE32位的浮點運算(IEEE32是國際電工委員會置頂的浮點書表示方式,主要內容是用四個字節來表示浮點數,可以表示的數據的負數范圍是(-22)128~-2127,2^-127~22^128)
  • 支持四元向量和四階矩陣
  • 提供分支和循環的控制語句
  • 具有高帶寬的內存處理能力
  • 支持1D,2D,3D的紋理查詢和使用能力,而且速度非常快
  • 支持繪制到紋理功能

渲染流水線

  • 含義: 計算機需要從一系列的頂點數據、紋理等信息出發、生成(或者說渲染)一張二維圖像的過程。
  • 渲染流程分為三個階段
    • 應用程序階段:(CPU)
      • 準備數據 eg.攝像機的位置、?視椎體、場景中的模型和光源等等
      • culling 粗粒度剔除 eg.將不可見的物體剔除
      • 輸出 輸出渲染所需的幾何信息(點、線、三角面),即渲染圖元
    • 幾何階段:(GPU)
      • 處理?渲染圖元進行逐頂點、逐多邊形的操作。頂點坐標轉換到屏幕空間。
      • 輸出屏幕空間的二維頂點坐標、每個頂點對應的深度值、著色等相關信息。
    • 光柵化階段?:(GPU)
      • 對上階段的數據進行插值,再進行逐像素的處理。

CPU與GPU之間的通信

  • CPU?流水線(即應用階段)
    • 把數據加載到顯存里
    • 設置渲染狀態
    • 調用Draw Call(發起方是CPU,接收方是GPU)
  • GPU流水線(即幾何階段和光柵化階段)
    [圖片上傳失敗...(image-260204-1513936425700)]
  • ?頂點著色器 : 必選,可編程,通常用于實現頂點坐標的變換,?計算頂點顏色。
  • 曲面細分著色器 :可選,用于細分圖元。
  • 幾何著色器 :可選,用于逐圖元的著色操作,或者用于產生更多的圖元。
  • 裁剪 : 可配置,將不是攝像機視野中的頂點裁剪掉。
  • 屏幕映射 : 不可編程,不可配置。把每個圖元的坐標轉換到屏幕坐標系。
  • 三角設置三角形遍歷階段都是固定函數的階段。
  • 片元著色器 :可編程,用于?實現逐片元的著色操作。
  • 逐片元操作 : 可配置,eg.顏色修改,深度緩,沖進行混合等。

三種語言:

  • OpenGl的GLSL
  • Direct3D的HLSL
  • NVIDIA的CG(CG編寫的可同時兼容?OpenGL和Direct平臺)

GPU流水線的兩個重要階段

  • 頂點著色器
    • 輸入: GPU前端模塊提取圖元信息(頂點位置,法線向量,紋理坐標(uv))等。
    • 操作: 頂點坐標空間轉換,法向量空間轉換,光照計算等(現在光照計算一般在片段著色器,比較細),然后將計算好的數據傳入指定寄存器中。
  • 片元著色器
    • 輸入:頂點著色器傳入的數據。
    • 操作:光照計算,uv擾動,紋理采樣等,最后輸出當前片段的顏色給光柵化階段(片段著色器是對每個獨立的顏色進行操作的)。

數學基礎

推薦《3D數學基礎:圖形與游戲開發》

CG語言基礎

  • CG語言的特性:
    Cg是一種類C的語言,他沿用了大量的C語言特性,但是也有不同之處。Cg語言是腳本性語言,不能編譯,調試和斷點;并且Cg語言的主要用途是繪制像素顏色到屏幕上,他不能處理文字類的內容。Cg語言對單精度浮點的數據類型是非常敏感的;Cg語言因為GPU的并發特性所以導致Cg語言的所有執行過程是并發式的;
  • CG語法
    • 基礎數據類型 :
      • float : 32位浮點數據
        float _Angle = 1.0
        
      • half : 16位浮點數據
        half _Angle = 1.0
        
      • int : 32位整形數據
        int _Angle = 1
        
      • fixed : 12位浮點數據
        fixed _Angle = 1
        
      • bool : ?布爾數據,用于判斷
        if(_Angle == 0)
        {
          colors = diffuses.rgb;
        }
        
      • Sampler 紋理對象,6類 : Sampler,sampler1D,sampler2D,sampler3D,samplerCUBE和samplerRECT
        sample2D _Diffuse;
        
    • 特殊的數據類型
      • 向量 : 一共擁有4種維度的向量,1-4之間
        float3 a = float3(0,1,2);
        
      • 矩陣 : 行和列都不得大于4和不得小于1
        float2*2 a = {sin@,0,1,3};
        
        矩陣在賦值的時候一定要人為的分開行與行之間的關系,但是程序只認識順序的賦值
      • 數組 : 因為CG是顯卡操作語,沒有內存,所以聲明的時候要制定大小
        float2 b[2];
        int arrayLen = b.length; // 結果是2
        float m[3][4];
        arrayLen = m.length;// 結果是3;
        arrayLen = m[1].length;// 結果是4;
        
      • 結構體 : 數據封裝作用
        struct a2v {
          float4 vertex : POSITION;
          float3 normal : NORMAL;
          float4 texcoord : TEXCOORD0;
          };
        
      • 表達式和控制語句
        • 關系操作符 :<,>,<=,>=,!=,==,
        • 邏輯操作符 :&&,||,!
        • 數學操作符 :+,—,*,/,%
        • 移位操作符 :>>
          int2 a = int2(0.0,0.0); 
          int2 b = a>>1; 
          
        • Swizzle操作符:
          float4(a, b, c, d).xyz    等價于  float3(a, b, c) 
          
        • 控制流語句 :if ,if-else while ,for,break
          • 點操作?符:只針對向量和結構
            v2f o;
              o.pos = UnityObjectToClipPos(v.vertex);
            
      • 行參修飾詞:
        • in: 表示當前行參是只能輸入的;
        • out:表示當前行參用來輸出數據的;
        • inout: 表示可以進行輸入和輸出;
      • 離散數據圖元信息:uniform
        • 只讀性,只要標有uniform標簽的變量,這個變量我們就不能初始化也不能修改其內容;
        • 使用范圍特性,只能存在于入口函數的行參上或者是全局的變量身上;
        • 他只能支持引擎向著色器傳入的數據,不能向外提交數據;
    • 語義
      [圖片上傳失敗...(image-525f9a-1513936425700)]
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容