本文章用于幫助自己學習,因此只記錄一些個人認為比較重要或者還不夠熟悉的內容,
原作者:http://blog.csdn.net/candycat1992/article/
第三章 Unity Shader基礎
3.1Unity Shader概述
最常見的流程:
由一個三維場景生成一張二維影像,
(1) 創建一個材質;
(2) 創建一個Unity Shader,并把它賦給上一步中創建的材質:
(3) 把材質賦給要渲染的物件;
(4) 在材質面板中調整Unity Shader的屬性,以得到滿意的效果,
3.2ShaderLab
Unity Shader是Unity為開發者提供的高層級的渲染抽象層,
在Unity中,所有的Unity Shader都是用ShaderLab來撰寫的,ShaderLab是Unity提供的撰寫Unity Shader的一種說明性語言,
3.3Unity Shader的結構
3.3.1給Shader起名
Shader "Custom/MyShader"
通過在字串中添加斜杠(“/”),可以控制Unity Shader在材質面板中出現的位置,
3.3.2Properties
Properties語意塊中包含了一系列屬性(property), 這些屬性將會出現在材質面板中,
Properties
{
Name ("display name", PropertyType) = DefaultValue
}
Name是屬性的名字,一般由一個下劃線開始,
display name是顯示在材質面板上的名字,
PropertyType是屬性的型別,
等號后面的DefaultValue就是需要給屬性指定的默認值,
-
Properties語意塊支持的屬性型別
| 屬性型別 | 默認值的定義語法 | 例子 |
|---|---|---|
| Int | number | ("Int”, Int) = 2 |
| Float | number | Float ("Float”, Float) = 1.5 |
| Range(min,max) | number | _Range(“Range”, Range(0.0, 5.0)) = 3.0 |
| Color | (number,number,number,number) | Color ("Color”, Color) = (1,13,1) |
| Vector | (number,number,number,number) | _Vector (“Vector”, Vector) = (2, 3, 6, 1) |
| 2D | “defaulttexture” {} | _2D ("2D”, 2D) = ”” {} |
| 3D | “defaulttexture” {} | 3D(”3D”,3D) = “black” () |
| Cube | “defaulttexture” {} | _Cube (“Cube”, Cube) = “white” (} |
3.3.3SubShader
SubShader語意塊中包含的定義通常如下:
SubShader {
//可選的
[Tags]
//可選的
[RenderSetup]
Pass (
}
// Other Passes
SubShader中定義了一系列Pass以及可選的狀態([RenderSetup])和標簽([Tags])設定,每個Pass定義了一次完整的渲染流程,狀態和標簽同樣可以在Pass宣告,但是,如果在Shader進行了這些設定,那么將會用于所有的Pass,
- 狀態設定可以設定顯卡的各種狀態,
表3.2 | 常見的渲染狀態設定選項 | |
狀態名稱 | 設定指令 | 解 釋 |
Cull | Cull Back | Front | Off | 設定剔除模式:剔除背面/正面/關閉 剔除 |
ZTest | ZTest Less Greater | LEqual | GEqual | Equal | NotEqual | Always | 設定深度測驗時使用的函式 |
ZWrite | ZWrite On | Off | 開啟/關閉深度寫入 |
Blend | Blend SrcFactor DstFactor | 開啟并設定混合模式 |
當在SubShader塊中設定了上述渲染狀態時,將會應用到所有的Pass,
- SubShader 的標簽
SubShader的標簽(Tags)是一個鍵值對(Key/Value Pair),它的鍵和值都是字串型別,它們用來告訴Unity的渲染引擎:SubShader我希望怎樣以及何時渲染這個物件,
Tags { "TagName1" = "Valuel" "TagName2" ="Value2" }
表3.3 | SubShader的標簽型別 | |
標簽型別 | 說 明 | 例 子 |
Queue | 控制渲染順序,指定該物體屬于哪一個渲染佇列,通 過這種方式可以保證所有的透明物體可以在所有不透 明物體后面被渲染(詳見第8章),我們也可以自定義 使用的渲染佇列來控制物體的渲染順序 | Tags ("Queue"1 = "Transparent" } |
RenderType | 對著色器進行分類,例如這是一個不透明的著色器, 或是一個透明的著色器等,這可以被用于著色器替換 (Shader Replacement)功能 | Tags {"RenderType" = "Opaque" } |
DisableBatching | 一些S泌S/wd”在使用Unity的批處理功能時會出現問 題,例如使用了模型空間下的坐標進行頂點影片(詳 見11.3節),這時可以通過該標簽來直接指明是否對該 SubShader使用批處理 | Tags ("DisableBatching" = "True" } |
ForceNoShadowCasting | 控制使用該SubShader的物體是否會投射陰影(詳見 8.4 節) | Tags { "ForceNoShadowCasting"= "True” } |
IgnoreProjector | 如果該標簽值為“True”,那么使用該SubShader的物 體將不會受Projector的影響,通常用于半透明物體 | Tags ("IgnoreProjector" = "True" } |
CanUseSpriteAtlas | 當該SubShade礦是用于精靈(sprites)時,將該標簽設 為 “False” | Tags {"CanUseSpriteAtlas" = "False"} |
PreviewType | 指明材質面板將如何預覽該材質,默認情況下,材質 將顯示為一個球形,我們可以通過把該標簽的值設為 “Plane” “SkyBox”來改變預型別別 | Tags ( "PreviewType" = "Plane" } |
上述標簽僅可以在SubShader中宣告,而不可以在Pass塊中宣告,
- Pass語意塊
Pass語意塊包含的語意如下:
Pass (
[Name]
[Tags]
[RenderSetup]
// Other code
}
首先定義名稱,例如:
Name "MyPassName"
可以使用ShaderLab的UsePass命令來直接使用其他Unity Shader中的 Pass,例如:
UsePass "MyShader/MYPASSNAME"
在使用UsePass命令時必須使用大寫形式的名字,
其次,可以對Pass設定渲染狀態,SubShader的狀態設定同樣適用于Pass,
Pass同樣可以設定標簽,但它的標簽不同于SubShader的標簽,
表3.4 | Pass的標簽型別 | |
標簽型別 | 說 明 | 例 子 |
LightMode | 定義該Pass在Unity的渲染流水線中的角色 | Tags { "LightMode" = "ForwardBase" } |
RequireOptions | 用于指定當滿足某些條件時才渲染該Pass,它的值是一個 由空格分隔的字串,目前,Unity支持的選項有: Soft Vegetation o在后面的版本中,可能會增加更多的選項 | Tags ( "RequireOptions" = "SoftVegetation"} |
3.3.4Fallback
緊跟在各個SubShader語意塊后面的,可以是一個Fallback指令,它用于告訴Unity:“如果上面所有的SubShader在這塊顯卡上都不能運行,那么就使用這個最低級的Shader, ”
它的語意如下:
Fallback "name"
//或者
Fallback Off//關閉Fallback
例:
Fallback "VertexLit"
3.4Unity Shader的形式
UnityShader最重要的任務是指定各種著色器所需的代碼,這些著色器代碼可以寫在SubShader語意塊中(表面著色器的做法),也可以寫在Pass語意塊中(頂點/片元著色器和固定函式著色器的做法),
Shader "MyShader"(
Properties {
//所需的各種屬性
}
SubShader (
//真正意義上的Shader代碼會出現在這里
//表面著色器(Surface Shader )或者
//頂點/片元著色器(Vertex/Fragment Shader )或者
// 固定函式著色器(Fixed Function Shader )
}
SubShader {
//和上一個SubShader類似
}
}
3.4.1表面著色器
表面著色器在本質上和頂點/片元著色器是一樣的,當給Unity提供一個表面著色器的時候,它在背后仍舊把它轉換成對應的頂點/片元著色器,
示例代碼:
Shader "Custom/Simple Surface Shader" {
SubShader {
Tags ( "RenderType** = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert
struct Input (
float4 color : COLOR;
);
void surf (Input IN, inout Surfaceoutput o) (
o.Albedo = 1;
}
ENDCG
}
Fallback “Diffuse”
)
表面著色器被定義在SubShader語意塊(而非Pass語意塊)中的 CGPROGRAM和ENDCG之間,
CGPROGRAM和ENDCG之間的代碼是使用CG/HLSL撰寫的,
3.4.1頂點/片元著色器
示例代碼:
Shader "Custom/Simple VertexFragment Shader" (
SubShader (
Pass (
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 vert(float4 v : POSITION) : SV_POSITION (
return mul (UNITY_MATRIX_MVP, v);
}
fixed4 frag() : SV_Target (
return fixed4(1.0,0.0,0.0,1.0);
}
ENDCG
}
}
}
頂點/片元著色器的代碼也需要定義在CGPROGRAM和ENDCG之間, 但不同的是,頂點/片元著色器是寫在Pass語意塊內,而非SubShader內的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/266405.html
標籤:其他
下一篇:Python中串列常用方法總結
