菲涅尔是人名,他发现,当我们站在水中,直直的往下看水面,是看不到反射的太阳光的。而当我们往远处看时,就能看到很强的反光,也就是成语波光粼粼所体现的。这一现象就被命名为 菲涅尔反射。
刚看这一节的时候觉得莫名其妙,感情书上一开始写的有问题,书上是这么写的:
当你的视线对着物体表面的时候,反射量会明显增加。
我对这句话的理解是 正对着表面的时候,反射量会增加。……真是误导。
不过好在代码是不会骗我的。
代码实现的效果是符合菲涅尔反射的,正对着物体表面,反射量减少。
转自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