菲涅尔是人名,他发现,当我们站在水中,直直的往下看水面,是看不到反射的太阳光的。而当我们往远处看时,就能看到很强的反光,也就是成语波光粼粼所体现的。这一现象就被命名为 菲涅尔反射。
刚看这一节的时候觉得莫名其妙,感情书上一开始写的有问题,书上是这么写的:
当你的视线对着物体表面的时候,反射量会明显增加。
我对这句话的理解是 正对着表面的时候,反射量会增加。……真是误导。
不过好在代码是不会骗我的。
代码实现的效果是符合菲涅尔反射的,正对着物体表面,反射量减少。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
创建新的场景 、材质、Shader。
完整Shader 代码如下:
Shader "CookBookShaders/Chapt4-5/FresnelReflections"
{
Properties
{
_MainTint("Diffuse Tint",Color)=(1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_Cubemap("Cubemap",CUBE)=""{}
_ReflectionAmount("Reflection Amount",Range(0,1))=1
_RimPower("Fresnel Falloff",Range(0.1,3))=2
_SpecColor("Specular Color",Color)=(1,1,1,1)
_SpecPower("Specular Power",Range(0,1))=0.5
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf BlinnPhong
#pragma target 3.0
float4 _MainTint;
sampler2D _MainTex;
samplerCUBE _Cubemap;
float _ReflectionAmount;
float _RimPower;
float _SpecPower;
struct Input
{
float2 uv_MainTex;
float3 worldRefl;
float3 viewDir;
};
void surf (Input IN, inout SurfaceOutput o)
{
half4 c = tex2D (_MainTex, IN.uv_MainTex)*_MainTint;
//首先求 法线 和 视线 夹角的cos值,然后使用saturate限定到(0,1)范围。因为是cos,所以当视线垂直表面,平行法线时,值最大为1.
//然后用 1 去减cos值,得到反转值。
//所以当视线垂直表面时,rim值最小,为0.
float rim=1.0 - saturate(dot(o.Normal,normalize(IN.viewDir)));
rim=pow(rim,_RimPower);
o.Albedo = c.rgb;
//所以当视线垂直表面时,rim=0,o.Emission =0 。视线越靠近垂直,反射越小。
o.Emission=(texCUBE(_Cubemap,IN.worldRefl).rgb * _ReflectionAmount)*rim;
o.Specular=_SpecPower;
o.Gloss=1.0;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
代码注释上面已经有了。
我也画了个图。
最终实现的效果
看到视线正对的那一块区域是很少反射的。
示例项目下载:
http://pan.baidu.com/s/1dF9Eu5b