Unity Shaders and Effects Cookbook:BlinnPhong光照模型
发表于2017-11-23
一张图来解释下镜面高光:
左侧是灯泡,灯泡发出光,到达顶点片段,然后被反射出来为 R 。
我们站在右侧观察,如果眼睛正好位于 光 的反射 的方向,即 眼睛位于 R 方向上,那么这个时候我们看到的光肯定是最强的。
随着眼睛 和 反射光 R 的夹角越大,那我们观察到Speculer Lighting 镜面光强度越小。
参考了OpenGL ES 学习教程(7.4):Specular Lighting镜面高光。
在GL中写 Specular Ligting 不是很复杂,然而在Unity 之中却更加简单。
Unity为我们提供了一个内置的高光光照模型函数 BlinnPhong ,我们只要指定光照模型为 BlinnPhone 就可以获得高光的效果。
下面来尝试。
首先新建一个Shader,一个Material,Material 中选择新创建的 Shader。
然后修改Shader 代码。
我们要使用 BlinnPhong 光照模型,但是请注意,BlinnPhong 光照模型 有一个内置变量 _SpecColor, 一定要在 Propertices 块中声明这个变量。
_MainTex ("Base (RGB)", 2D) = "white" {} _MainTint("Diffuse Tint",Color)=(1,1,1,1) //漫反射 _SpecColor("Specular Color",Color)=(1,1,1,1) //高光颜色 _SpecPower("Specular Power",Range(0,1))=0.5 //高光强度
然后在 CGPROGRAM 中声明我们自定义的其它 变量
sampler2D _MainTex; float4 _MainTint; float _SpecPower;
然后指定光照模型为 BlinnPhong
#pragma surface surf BlinnPhong
完整Shader代码如下:
Shader "CookBookShaders/Build-in Specular" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _MainTint("Diffuse Tint",Color)=(1,1,1,1) _SpecColor("Specular Color",Color)=(1,1,1,1) _SpecPower("Specular Power",Range(0,1))=0.5 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 //注意:这里指定了采用哪种光照模型,这里指定为 Build-in 的BlinnPhong; CGPROGRAM #pragma surface surf BlinnPhong //注意 : _SpecColor 是Unity Build-in变量,无需自己在SubShader中声明变量,只需在 Properties块中声明该变量;就是说变量是内置的,但是这个变量在编辑器中显示什么名字是我们来指定的(之前说过Propertices块中声明的变量是编辑器和CG的桥梁、中间件) sampler2D _MainTex; float4 _MainTint; float _SpecPower; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { half4 c = tex2D (_MainTex, IN.uv_MainTex)*_MainTint; o.Specular=_SpecPower; //传递到 BlinnPhong 光照模型函数中。 o.Gloss=1.0; //光滑度,用来控制高光的清晰度,值越大 越清晰,比如一块慢慢生锈的铁,就可以用Gloss慢慢减小,实现高光越来越弱的效果 o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
看看默认材质 和 Specular 材质的对比
示例工程下载:http://pan.baidu.com/s/1nu7KLyL