这篇文章最好与前一篇连着看,自己可做比较。
1.BlinnPhong 模型
Blinn是计算和估计镜面反射的另一种更有效的方法。这是通过从 视图方向和光方向获得半矢量来完成饿。JimBlinn将它带入来Cg的世界。他发现只获得半矢量而不是计算我们自己的反射 矢量效率更高。它减少了代码和处理时间。如果你实际查看UnityCG.cginc文件中包含的内置BlinnPhong光照模型,你会注意到它也使用来半矢量,因此它被命名为BlinnPhong,它只是完整的Phong的简单版本。
a..创建一个shader命名为BlinnPhong。
b.创建一个material命名为BlinnPhongMat。
c.移走所以才当前属性,并在属性块中添加如下属性,这样我们就可以控制镜面高光的外观:
_MainTint("Diffuse Tint",Color) = (1,1,1,1)
_MainTex("Base (RGB)",2D) = "white" {}
_SpecularColor("Specular Color",Color) = (1,1,1,1)
_SpecPower("Specular Power",Range(0.1,60)) = 3
d.并在CGPROGRAM中添加相关变量‘
sampler2D _MainTex;
float4 _MainTint;
float4 _SpecularColor;
float _SpecPower;
e. 现在是时候创建我们自定义光照模型来处理我们的漫反射和高光计算。
fixed4 LightingCustomBlinnPhong(SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
{
float NdotL = max(0, dot(s.Normal, lightDir));
float3 halfVector = normalize(lightDir + viewDir);
float NdotH = max(0, dot(s.Normal, halfVector));
float spec = pow(NdotH, _SpecPower) * _SpecularColor;
float4 color;
color.rgb = (s.Albedo * _LightColor0.rgb * NdotL) + (_LightColor0.rgb * _SpecularColor.rgb * spec) * atten;
color.a = s.Alpha;
return color;
}
h.更新surf函数如下表
void surf(Input IN, inout SurfaceOutput o)
{
half4 c = tex2D(_MainTex, IN.uv_MainTex) * _MainTint;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
i.为了完成我们的shader,我们需要通过使用以下代码修改 #pragma语句来告诉我们的CGPROGRAM块使用我们的自定义光照模型而不是内置模型:
CPROGRAM
#pragma surface surf CustomBlinnPhong
源码如下:
Shader "Custom/BlinnPhong" {
Properties {
_MainTint("Diffuse Tint",Color) = (1,1,1,1)
_MainTex("Base (RGB)",2D) = "white" {}
_SpecularColor("Specular Color",Color) = (1,1,1,1)
_SpecPower("Specular Power",Range(0.1,60)) = 3
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf