Unity Shader (一)ShaderLab 語法


一、什么是Shader

 

Shader(着色器):是可以在GPU上運行的一段程序,通過Shader可以進行一些渲染相關的設置。

 

二、什么是ShaderLab

 

目前面向GPU的編程有三種高級圖像語言:HLSL語言,GLSL語言,Cg語言。

HLSL語言:High Level Shading Language,由Microsoft公司提供,通過Direct3D圖形軟件庫來編寫的着色器語言。

GLSL語言:OpenGL Shading Language,由OpenGL安委會提供,在OpenGL中進行着色器編程的語言。

Cg語言:C for Graphics,由NVIDIA公司和Microsoft公司合作提供,有自己的一套關鍵字和函數庫,獨立於三維編程接口,在Direct3D和OpenGL上都可工作。

 

ShaderLab: Unity 自己又封裝了一層CG/HLSL/GLSL的接口,但為了實現跨平台,Unity重點支持Cg着色器語言。

 

三、ShaderLab語法

 

基本結構:

Shader "name" { Properties{ } Subshader{ }}

下面是一個最簡單的shader

// 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
        }
    }
}

1、Shader "name"{ }定義了一個名字為“name”的shader。

2、Properties { } : 屬性

定義了一些屬性參數,可在Unity編輯器的“Inspector”面板中編輯和調整。

  Properties {
        _Color是變量名 ("Main Color"是在“Inspector”中的名字, Color是變量類型) = (1,.5,.5,1)是默認值          
 }

Properties 類型

類型 說明
Range(min,max) 在(min,max)范圍內的浮點數
Float 浮點數
Int 整型
Color 顏色 RGBA
Vector 四維向量
2D 2D紋理
3D 3D紋理
Cube 立方體貼圖紋理
Rect 矩形紋理
  • _Name - 屬性的名字,簡單說就是變量名,在之后整個Shader代碼中將使用這個名字來獲取該屬性的內容
  • Display Name - 這個字符串將顯示在Unity的材質編輯器中作為Shader的使用者可讀的內容
  • type - 這個屬性的類型,可能的type所表示的內容有以下幾種:
    • Color - 一種顏色,由RGBA(紅綠藍和透明度)四個量來定義;
    • 2D - 一張2的階數大小(256,512之類)的貼圖。這張貼圖將在采樣后被轉為對應基於模型UV的每個像素的顏色,最終被顯示出來;
    • Rect - 一個非2階數大小的貼圖;
    • Cube - 即Cube map texture(立方體紋理),簡單說就是6張有聯系的2D貼圖的組合,主要用來做反射效果(比如天空盒和動態反射),也會被轉換為對應點的采樣;
    • Range(min, max) - 一個介於最小值和最大值之間的浮點數,一般用來當作調整Shader某些特性的參數(比如透明度渲染的截止值可以是從0至1的值等);
    • Float - 任意一個浮點數;
    • Vector - 一個四維數;
  • defaultValue 定義了這個屬性的默認值,通過輸入一個符合格式的默認值來指定對應屬性的初始值(某些效果可能需要某些特定的參數值來達到需要的效果,雖然這些值可以在之后在進行調整,但是如果默認就指定為想要的值的話就省去了一個個調整的時間,方便很多)。
    • Color - 以0~1定義的rgba顏色,比如(1,1,1,1);
    • 2D/Rect/Cube - 對於貼圖來說,默認值可以為一個代表默認tint顏色的字符串,可以是空字符串或者”white”,”black”,”gray”,”bump”中的一個
    • Float,Range - 某個指定的浮點數
    • Vector - 一個4維數,寫為 (x,y,z,w)
  • 另外還有一個{option},它只對2D,Rect或者Cube貼圖有關,在寫輸入時我們最少要在貼圖之后寫一對什么都不含的空白的{},當我們需要打開特定選項時可以把其寫在這對花括號內。如果需要同時打開多個選項,可以使用空白分隔。可能的選擇有ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal中的一個,這些都是OpenGL中TexGen的模式,具體的留到后面有機會再說。

3、SubShader

 

基本結構:

Subshader { [Tags] [CommonState] Passdef [Passdef ...] }

Tags

表面着色器可以被若干的標簽(tags)所修飾,而硬件將通過判定這些標簽來決定什么時候調用該着色器。比如我們的例子中SubShader的第一句

Tags { "RenderType"="Opaque" }

告訴了系統應該在渲染非透明物體時調用我們。Unity定義了一些列這樣的渲染過程,與RenderType是Opaque相對應的顯而易見的是"RenderType" = "Transparent",表示渲染含有透明效果的物體時調用。在這里Tags其實暗示了你的Shader輸出的是什么,如果輸出中都是非透明物體,那寫在Opaque里;如果想渲染透明或者半透明的像素,那應該寫在Transparent中。

另外比較有用的標簽還有"IgnoreProjector"="True"(不被Projectors影響),"ForceNoShadowCasting"="True"(從不產生陰影)以及"Queue"="xxx"(指定渲染順序隊列)。這里想要着重說一下的是Queue這個標簽,如果你使用Unity做過一些透明和不透明物體的混合的話,很可能已經遇到過不透明物體無法呈現在透明物體之后的情況。這種情況很可能是由於Shader的渲染順序不正確導致的。Queue指定了物體的渲染順序,預定義的Queue有:

  • Background - 最早被調用的渲染,用來渲染天空盒或者背景
  • Geometry - 這是默認值,用來渲染非透明物體(普通情況下,場景中的絕大多數物體應該是非透明的)
  • AlphaTest - 用來渲染經過Alpha Test的像素,單獨為AlphaTest設定一個Queue是出於對效率的考慮
  • Transparent - 以從后往前的順序渲染透明物體
  • Overlay - 用來渲染疊加的效果,是渲染的最后階段(比如鏡頭光暈等特效)

這些預定義的值本質上是一組定義整數,Background = 1000, Geometry = 2000, AlphaTest = 2450, Transparent = 3000,最后Overlay = 4000。在我們實際設置Queue值時,不僅能使用上面的幾個預定義值,我們也可以指定自己的Queue值,寫成類似這樣:"Queue"="Transparent+100",表示一個在Transparent之后100的Queue上進行調用。通過調整Queue值,我們可以確保某些物體一定在另一些物體之前或者之后渲染,這個技巧有時候很有用處。

 

LOD

它是Level of Detail的縮寫。這個數值決定了我們能用什么樣的Shader。在Unity的Quality Settings中我們可以設定允許的最大LOD,當設定的LOD小於SubShader所指定的LOD時,這個SubShader將不可用。Unity內建Shader定義了一組LOD的數值,我們在實現自己的Shader的時候可以將其作為參考來設定自己的LOD數值,這樣在之后調整根據設備圖形性能來調整畫質時可以進行比較精確的控制。

  • VertexLit及其系列 = 100
  • Decal, Reflective VertexLit = 150
  • Diffuse = 200
  • Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
  • Bumped, Specular = 300
  • Bumped Specular = 400
  • Parallax = 500
  • Parallax Specular = 600

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM