Unity3d開發(一)ShaderLab 入門 語法格式
Ahead
好長時間沒更新部落格了,究其原因,是我想嘗試Wiki這種形式來整理知識。總體來說,它還是不錯的,不過不適合我。所以,還是迴歸部落格吧。
Shader Lab
ShaderLab 是Unity3d自己封裝的一個呼叫CG/HLSL/GLSL的介面。相關資訊可以參考:聖典翻譯的新手
基本格式
shaderLab 程式碼一般遵循以下格式:
Shader "MyShader/ShaderName" { Properties { _Color ("Main Color", Color) = (1,1,1,0.5) _MainTex ("Texture", 2D) = "white" { } } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" //--snip-- struct v2f { float4 pos :SV_POSITION; float3 color : COLOR0; }; v2f lv1(appdata_base v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); o.color = v.normal * 0.5 +0.5; return o; } half4 lv2(v2f i) : COLOR { return half4(i.color,1); } ENDCG } } FallBack "VertexLit" }
屬性設定
Properties {
`InnerName` ( `showName`,`type`) = `defaultValue`
}
其中型別與預設值對應如下:
- Color (r,g,b,a)
- Range(min,max) 2.4
- 2D "white" {}
- Float 2.4
surface shader
以下內容詳細可以參考此處
定義
使用 #pragma surface
這個指令可用編寫表面著色器。
#pragma surface surfaceFunction lightModel [optionalparams]
所需引數:
surfaceFunction - 表示Cg函式中有表面著色器(surface shader)程式碼。這個函式的格式應該是這樣:
void surf (Input IN,inout SurfaceOutput o)
Input是你自己定義的結構。Input結構中應該包含所有紋理座標(texture coordinates)和和表面函式(surfaceFunction)所需要的額外的必需變數。
lightModel -在光照模式中使用。內建的是Lambert (diffuse)和 BlinnPhong (specular)。如果想編寫自己的光照模式,請參考:自定義光照模式。
cginc
對於預定義的巨集和函式,Unity將她們放進了許多包含檔案中。在Mac上,它的目錄為 Contents/CGIncludes/xxx.cginc 例如常用的:UnityCG.cginc, lighting.cginc 等。當然我們也可以自己編寫。將檔案字尾更改成.cginc
#include "YourCGInclude.cginc"
即可。INPUT
Input 這個輸入結構通常擁有著色器需要的所有紋理座標(texture coordinates)。紋理座標(Texture coordinates)必須被命名為“uv”後接紋理(texture)名字。(或者uv2開始,使用第二紋理座標集)
例如:
Properties {
_MainTex ("Texture", 2D) = "white" {}
_BumpMap ("Bumpmap", 2D) = "bump" {}
}
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
sampler2D _MainTex;
sampler2D _BumpMap;
OUTPUT
struct SurfaceOutput {
half3 Albedo; //反射率
half3 Normal; //法線
half3 Emission; //自發光,用於增強物體自身的亮度,使之看起來好像可以自己發光
half Specular; //鏡面
half Gloss; //光澤
half Alpha; //透明
};
subshader Tag
使用Tags可以為subshader指定屬性:
Tags { "TagName1" = "Value1" "TagName2" = "Value2" }
詳細的屬性使用可以參考Unity手冊中 subshader tags章節。
指令碼中呼叫
在指令碼中可以動態設定shader的值,例如:
[ExecuteInEditMode]
public class caller : MonoBehaviour {
public Color diffColor;
void Update()
{
renderer.sharedMaterial.SetColor("_color",diffColor);
}
}
其中,shader中有名為_color的uniform變數 例如:
Shader "Learn/ColorShader" {
Properties {
}
SubShader {
Tags { "Queue"= "Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
Pass{
CGPROGRAM
#pragma vertex v2f
#pragma fragment frag
#include "UnityCG.cginc"
uniform fixed4 _color;
struct InputVertex
{
float4 pos : POSITION;
} ;
struct Output
{
float4 pos :SV_POSITION;
float4 col :COLOR0;
} ;
Output v2f(InputVertex input)
{
Output o;
o.pos = mul(UNITY_MATRIX_MVP,input.pos);
o.col = _color;
return o;
}
half4 frag(Output o): COLOR
{
// return half4(1.0,0.4,0.4,1);
return o.col;
}
ENDCG
}
}
FallBack "Diffuse"
}
自定義光照
#pragma surface surf `FuncName`
- half4 Lighting
FuncName
(SurfaceOutput s, half3 lightDir, half atten) {} - half4 Lighting
FuncName
(SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {} - half4 Lighting
FuncName
(SurfaceOutput s, half4 light) {}
如果你覺得這篇文章對你有幫助,可以順手點個頂,不但不會喜當爹,還能讓更多人能看到它...