下面着重分析一下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"
}