1. 程式人生 > >Unity Shader 之一 語法基礎

Unity Shader 之一 語法基礎

unity shaderlab 的語法基礎 ,用來做個人備忘查詢
ShaderLab Syntax Unity中的所有Shader都是用一種叫做"Shader Lab"的陳述性語言(declarative language)寫的。在Shader中通過逐層巢狀的大括號來宣告包括在材質面板看到的一系列變數、使用的渲染模式、硬體不支援時的fallback等。而真正的"shader程式碼"夾在CGPROGRAM...ENDCG之間的程式碼片段。本節就合租要介紹這些巢狀的語法。而真正CGPROGRAM程式碼段是通過常規的HLSL/Cg 著色器語言完成的。
  • ShaderLab 
    •  Shader "shadername" { [Properties]  Subshaders [Fallback] [CustomEditor] }
    • shadername:
      • "shadername "是你通過inspector面板為材質選擇shader時看到的名字,可以用"/"生成類似二級三級選單的形式,例如" custom/example"
    • Properties:
      • shader中用到的一些額外引數,可以在材質的inspcector面板中看到,例如顏色,貼圖等
    • Subshaders:
      • 每一個Shder都是由一個或者多個sub-shader組成的。當載入一個shader的時候,unity 會從頭遍歷這一系列的subshader,並且選擇裝置支援的第一個宿便是的人。如果沒有可用的subshaders,untiy就會選擇fallback shader。
      • 如果你想讓你的遊戲在最新的顯示卡上有完美的表現,有不想遊戲只能讓這些有高階顯示卡的玩家體驗,就要編寫多個subshader。
      • Shader層面的"level of detail (LOD)"和"shader replacement"是兩項依賴於subshader的技術
    • Exampler
// colored vertex lighting Shader "Simple colored lighting" {      // a single color property      Properties {           _Color ("Main Color", Color) = (1,.5,.5,1) }      // define one subshader      SubShader      {           // a single pass in our subshader           Pass {                // use fixed function per-vertex lighting                Material {                     Diffuse [_Color] } Lighting On                }      } }
  • ShaderLab : Properties
    • Shader 可以定義各種各樣的引數來讓美術在unity 材質球的inspector面板中通過調整引數來進行創作。
    • Syntax: Properties{ Property[Property ...]}
    • 數值和滑動條
      • 變數名 ("inspector 中顯示的名字" ,Range(min,max))=default value        //顯示為滑動條
      • name ("display name" ,Float)=default value
      • name ("display name",Int)=default
    • 顏色和向量
      • name ("display name" ,Color)=(1,1,1,1)     //預設的(r g b a)值
      • name ("display name",Vector)=(0,0,0,0) //預設的(x y z w)值
    • 貼圖
      • name("display name",2D)="default texture" {} //2D texture
      • name ("display name",Cube)="default texture"{} //cubemap
      • name("display name",3D)="default texture" {} //3D(volume)
  • 細節
    • shader 中自定義的變數通過 "name"欄位引用,而且在unity中我們通常以下劃線作為自定義變數的開頭,例如"_MainTex"。在material inspector面板中顯示的名字則是"display name",所以display name可以為中文例如 "法線貼圖"。
    • 對於Range 、Float、Color和Vector這些變數的預設值可以直接用數字描述
    • 而對於Texture(2D ,Cube)預設值可以是空字串也可以是內建的貼圖名字如:"white","black","gray" or "bump"
    • 在固定功能shader中可以直接通過變數名來獲取變數的值,而SurfaceShader 以及vertex &fragment shader中需要額外宣告一次
    •  變數名前面可以新增用中括號括起來的描述性屬性
      • [HideInInspector]
      • [NoScaleOffset] -用來修飾貼圖變數,在inspcetor 面板中不再顯示該貼圖的tilling/offset 屬性
      • [Normal] -用來修飾貼圖變數,該貼圖必須是一個法線貼圖
      • [HDR] -用來修飾貼圖變數,該貼圖必須是一個high-dynamic range(HDR)貼圖
      • [Gamma]- indicates that a float/vector property is specified as sRGB value in the UI (just like colors are), and possibly needs conversion according to color space used. SeeProperties in Shader Programs.
      • [PerRendererData]-indicates that a texture property will be coming from per-renderer data in the form of a MaterialPropertyBlock. Material inspector changes the texture slot UI for these properties.
    • Example
// properties for a water shader Properties {      _WaveScale ("Wave scale", Range (0.02,0.15)) = 0.07 // sliders      _ReflDistort ("Reflection distort", Range (0,1.5)) = 0.5      _RefrDistort ("Refraction distort", Range (0,1.5)) = 0.4      _RefrColor ("Refraction color", Color) = (.34, .85, .92, 1) // color      _ReflectionTex ("Environment Reflection", 2D) = "" {} // textures      _RefractionTex ("Environment Refraction", 2D) = "" {}      _Fresnel ("Fresnel (A) ", 2D) = "" {}      _BumpMap ("Bumpmap (RGB) ", 2D) = "" {} }      
  • ShaderLab:SubShader
    • Unity中的每一個Shader都由一系列的subshader構成。當unity需要展示一個模型時,它會找到使用的shader並且找到在目標裝置上第一個可用的subshader來執行,而不會執行剩餘的其他subshader
    • Syntax 
      • Subshader{[Tags] [CommonState] Passdef [Passdef...]}
    • Details
      • subshader 定義了一系列的渲染通道,並且可以設定對所有通道都可用的一些狀態以及subshader 層級的標籤
      • 因為subshader內定義的每一個pass都會導致該物體被渲染一次,而對物體的一次渲染開銷昂貴,所以儘可能少的定義pass,但必須有一個。
      • 在unity判斷哪一個subshader可以用的時候,會對該物件的每一個pass都執行一次。
      • pass有三種類型:regular Pass ,Use pass or Grab Pass
      • 所有在 pass的語句塊內的程式碼都可以放在subshader塊內,而subshader塊內的內容會在所有的通道中執行
    • Example
// ...   SubShader { //一個之定義了一個通道的subshader       Pass {           Lighting Off       //關閉所有光照效果           SetTexture [_MainTex] {} //用_MainTex這個貼圖渲染模型      } } // ...
  • ShaderLab:Pass
    • Syntax
      • Pass{[Name and Tags] [RenderSetup]}
    • Name and tags
      • 一個Pass可以定義自己的名字和任意數量的標籤 
      • 通過 "tagname"="value" 的形式,告訴渲染引擎要做什麼
    • Render state set-up  設定顯示卡的渲染狀態
      • Cull 設定多邊形剔除模式 ,模型被剔除的部分不參與渲染
        • Cull Back | Front |Off  // 背面/前面/關閉(無剔除)  剔除
      • ZTest 設定深度緩衝測試模式
        • ZTest (Less | Greater |LEqual |GEqual |Equal|NotEqual |Always
      • ZWrite 設定深度緩衝寫模式
        • ZWrite On|Off
      • Offset 設定 Z 緩衝的深度便宜
        • Offset OffsetFactor,OffsetUnits
      • Blend 設定alpha混合,alpha 操作和alpha-to-coverage 模式
        • Blend sourceBlendMode destBlendMode
        • Blend sourceBlendMode destBelndMode ,alphaSourceBlendMode alphaDestBlendMode
        • BlendOp colorOp
        • BlendOp colorOp ,alphaOp
        • AlphaToMask On | Off
      • ColorMask
        • ColorMask RGB | A | 0 | any combination of R, G, B, A
        •  設定顏色通道的遮罩 。 ColorMask 0 turns off rendering to all color channels.
      • 歷史遺留的 固定功能 shader 的指令
        • 有一些指令用來寫固定功能管線shader.而這些內容是即將被丟棄的,因為通過寫 表面著色器或者 shader programs 能夠更加靈活。然而對某些非常簡單的固定功能的shader,使用這些指令會非常簡單
        • 以下所有指令在非固定功能shader中都是無效的。
        • Fixed-function Lighting and Material
          • Lighting On | Off
          • Material {Material Block}
          • SeparateSpecular On |Off
          • Color Color-value
          • ColorMaterial AmbientAndDiffuse |Emission
          • All of these control fixed-function per-vertex Lighting: they turn it on, set up Material colors, turn on specular highlights, provide default color (if vertex Lighting is off), and controls how the mesh vertex colors affect Lighting. See documentation on Materials for more details.
        • Fixed-function Fog
          • Fog {Fog Block}
          • Fog Block Content
            • Mode Off |Global |Linear |Exp |Exp2
            • Color ColorValue
            • Density FloatValue
            • Range FloatValue,FloatValue
          • 預設霧效的設定在 Lighting 視窗中配置
        • Fixed-function AlphaTest
          • AlphaTest (Less |Greater |LEqual |GEqual |Equal |NotEqual|Always) CutoffValue
          • alpha 測試
            • AlphaTest comparison AlphaValue //Set up the alpha to only render pixels whose alpha value is within a certain range
        • Fixed-function Texture conbiners
          • 在渲染狀態設定之後,使用SetTexturn命令來制定渲染用的貼圖和貼圖的組合模式
          • SetTexturen textureProperty {combine options}
      • Details Shader passes interact with Unity’s rendering pipeline in several ways; for example, a Pass can indicate that it should only be used for  deferred shading using the  Tagscommand. Certain passes can also be executed multiple times on the same GameObject; for example, in  forward rendering the “ForwardAdd” pass type is executed multiple times based on how many Lights are affecting the GameObject. See documentation on the  Render Pipeline for more details.


  • ShaderLab:Fallback
    • 在所有Subshader的定義結束之後,可以宣告一個Fallback。用來告訴顯示卡,如果沒有可以用的subshader,試試看這裡的這個shader能不能用。
    • Syntax
      • Fallback "name"
      • Fallback Off
        • 明確說明沒有fallback ,而且不會列印警告,即使沒有可用的subshader
  • ShaderLab:Category
    • Category 是對其下的命令的邏輯分組。例如,如果你的shader有多個subshader,並且每一個subshader都需要關閉霧效和以及一樣的blending mode ,就可以使用Category:
Shader "example" { Category {      Fog { Mode Off }      Blend One One      SubShader { // ... }      SubShader { // ... }      // ...      } }
    • Category 程式碼塊,僅僅影響shader的解析,並不影響shader的執行。