/*
*
版本:0.1
最后修改:2012-08-10
撰寫:李現民
Unity3D中主要用到的shader(着色器)有三種,除了常規的vertex shader與fragment shader外,還有一類稱為surface shader。Unity3D自帶文檔中關於surface shader的介紹非常少,除了有一些示例外,surface shader的結構定義,調用時機,參數的含義都被略了,對我等初學者而言,這無疑加大了學習難度。
前兩天在網上查相關資料時,偶然發現了一篇文章,從里面提到的代碼框架看,surface shader的主方法原來是在fragment shader中調用的,使用一個inout類型SurfaceOutput參數。
http://aras-p.info/blog/2010/07/16/surface-shaders-one-year-later/
下面着重分析一下surface shader中是如何使用BlinnPhong光照模型的,為以后寫代碼做鋪墊。源文件取自Unity3D官網下載的builtin_shaders, 源文件名為Normal-Glossy.shader,描述了最基本的鏡面反射是如何設計的
* */
Shader " Specular "
{
Properties
{
// 主色調,用於定義物體的基色
_Color ( " Main Color ", Color) = ( 1, 1, 1, 1)
// 高光顏色,如果使用BlinnPhong光照模型,則定義高光時必須命名為_SpecColor,並且,只有變量定義,在surface shader中看不到是在哪里使用的,使用該變量的地方被隱藏了
_SpecColor ( " Specular Color ", Color) = ( 0.5, 0.5, 0.5, 1)
// 材質的光澤度,反映物體表面的光澤程度,又叫高光指數,定義范圍(0, 1]之間,其值越大,反射光越集中
_Shininess ( " Shininess ", Range ( 0.01, 1)) = 0.078125
// 主紋理,用於定義物體基色
_MainTex ( " Base (RGB) Gloss (A) ", 2D) = " white " {}
}
SubShader
{
// 繪制類型,只是用於Replaced Shaders的標記,並不是必須的。
// 如果需要定義對象的繪制順序,請使用Queue標記
Tags { " RenderType "= " Opaque " }
LOD 300
CGPROGRAM
// 定義着色器類型為surface,着色器入口方法為surf(),光照模型為BlinnPhong
#pragma surface surf BlinnPhong
sampler2D _MainTex;
fixed4 _Color;
half _Shininess;
struct Input
{
// Unity3D中shader的默認規則,紋理定義前面加uv前綴代表是對應的紋理坐標
float2 uv_MainTex;
};
void surf (Input input, inout SurfaceOutput output)
{
// 取主紋理的對應當前像素點的值
fixed4 tex = tex2D(_MainTex, input.uv_MainTex);
// Albedo反照率,即物體反射光的數量與外來光數量的比值。
// Albedo = 主紋理 x 主色調,反映了物體的基色,與任何光相關的信息(比如diffuse, shiness等)無關
output.Albedo = tex.rgb * _Color.rgb;
// Gloss光滑度[0, 1],用於控制反射的模糊程度,值越大,高光反射越清晰,反之則越模糊。
// 光滑度的“滑”是面的概念,代表物體整體的光滑程度
// 比如說,同樣一塊金屬,在它生銹的過程中,其反射就會慢慢變弱,可以通過Gloss值控制
// 實際上它是針對高光計算結果的附加系數
output.Gloss = tex.a;
// Alpha,不透明度[0, 1]:Alpha=0,代表物體完全透明;Alpha=1,代表物體完全不透明
output.Alpha = tex.a * _Color.a;
// Shininess光澤度[0, 1],又叫高光指數或鏡面反射指數,注意,它在SurfaceOutput結構中的命名(Specular)很容易讓人誤解為它是高光強度,其實不然,它是高光指數
// 光澤度的“澤”是點的概念,代表物體某個高光點的光澤程度
output.Specular = _Shininess;
}
ENDCG
}
// 如果當前GPU不支持本shader,默認使用VertexLit
Fallback " VertexLit "
}
版本:0.1
最后修改:2012-08-10
撰寫:李現民
Unity3D中主要用到的shader(着色器)有三種,除了常規的vertex shader與fragment shader外,還有一類稱為surface shader。Unity3D自帶文檔中關於surface shader的介紹非常少,除了有一些示例外,surface shader的結構定義,調用時機,參數的含義都被略了,對我等初學者而言,這無疑加大了學習難度。
前兩天在網上查相關資料時,偶然發現了一篇文章,從里面提到的代碼框架看,surface shader的主方法原來是在fragment shader中調用的,使用一個inout類型SurfaceOutput參數。
http://aras-p.info/blog/2010/07/16/surface-shaders-one-year-later/
下面着重分析一下surface shader中是如何使用BlinnPhong光照模型的,為以后寫代碼做鋪墊。源文件取自Unity3D官網下載的builtin_shaders, 源文件名為Normal-Glossy.shader,描述了最基本的鏡面反射是如何設計的
* */
Shader " Specular "
{
Properties
{
// 主色調,用於定義物體的基色
_Color ( " Main Color ", Color) = ( 1, 1, 1, 1)
// 高光顏色,如果使用BlinnPhong光照模型,則定義高光時必須命名為_SpecColor,並且,只有變量定義,在surface shader中看不到是在哪里使用的,使用該變量的地方被隱藏了
_SpecColor ( " Specular Color ", Color) = ( 0.5, 0.5, 0.5, 1)
// 材質的光澤度,反映物體表面的光澤程度,又叫高光指數,定義范圍(0, 1]之間,其值越大,反射光越集中
_Shininess ( " Shininess ", Range ( 0.01, 1)) = 0.078125
// 主紋理,用於定義物體基色
_MainTex ( " Base (RGB) Gloss (A) ", 2D) = " white " {}
}
SubShader
{
// 繪制類型,只是用於Replaced Shaders的標記,並不是必須的。
// 如果需要定義對象的繪制順序,請使用Queue標記
Tags { " RenderType "= " Opaque " }
LOD 300
CGPROGRAM
// 定義着色器類型為surface,着色器入口方法為surf(),光照模型為BlinnPhong
#pragma surface surf BlinnPhong
sampler2D _MainTex;
fixed4 _Color;
half _Shininess;
struct Input
{
// Unity3D中shader的默認規則,紋理定義前面加uv前綴代表是對應的紋理坐標
float2 uv_MainTex;
};
void surf (Input input, inout SurfaceOutput output)
{
// 取主紋理的對應當前像素點的值
fixed4 tex = tex2D(_MainTex, input.uv_MainTex);
// Albedo反照率,即物體反射光的數量與外來光數量的比值。
// Albedo = 主紋理 x 主色調,反映了物體的基色,與任何光相關的信息(比如diffuse, shiness等)無關
output.Albedo = tex.rgb * _Color.rgb;
// Gloss光滑度[0, 1],用於控制反射的模糊程度,值越大,高光反射越清晰,反之則越模糊。
// 光滑度的“滑”是面的概念,代表物體整體的光滑程度
// 比如說,同樣一塊金屬,在它生銹的過程中,其反射就會慢慢變弱,可以通過Gloss值控制
// 實際上它是針對高光計算結果的附加系數
output.Gloss = tex.a;
// Alpha,不透明度[0, 1]:Alpha=0,代表物體完全透明;Alpha=1,代表物體完全不透明
output.Alpha = tex.a * _Color.a;
// Shininess光澤度[0, 1],又叫高光指數或鏡面反射指數,注意,它在SurfaceOutput結構中的命名(Specular)很容易讓人誤解為它是高光強度,其實不然,它是高光指數
// 光澤度的“澤”是點的概念,代表物體某個高光點的光澤程度
output.Specular = _Shininess;
}
ENDCG
}
// 如果當前GPU不支持本shader,默認使用VertexLit
Fallback " VertexLit "
}
