Unity3D ShaderLab 立方体图的菲涅尔反射
菲涅尔反射是反射类型中比较常见的一种类型,当我们的视线正对物体表面,那么反射量会明显增加,
我们几乎可以在任何支持反射类型的物体表面看到这种情况,我们接下来就来实现这种反射效果过。
还是先创建Shader和 Material,沿用上一节的立方体图。代码变动较少,直接看下面的完成代码:
code start --------------------------------------------------------------------------
Shader "91YGame/FresnelReflection" { Properties { _MainTint("Diffuse Tint",Color)=(1,1,1,1) _MainTex ("Base (RGB)", 2D) = "white" {} _CubeMap("CubeMap",CUBE)=""{} _ReflAmount("Reflection Amount",Range(0.1,3))=0.5 _RimPower("Fresnel Falloff",Range(0.1,3))=1 //反射颜色; _SpecColor("Specular Color",Color)=(1,1,1,1) //反射强度值; _SpecPower("Specular Power",Range(0.02,1))=0.5 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM //使用unity内置的BlinnPhong光照模型; #pragma surface surf BlinnPhong //使用Shader Mode 3.0; #pragma target 3.0 sampler2D _MainTex; samplerCUBE _CubeMap; float4 _MainTint; float _ReflAmount; 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); //反转saturate函数获得的0-1之间的值; float rim = 1.0 - saturate(dot(o.Normal,normalize(IN.viewDir))); rim = pow(rim,_RimPower); //计算反射率; o.Albedo = c.rgb*_MainTint.rgb; //计算自发光并赋值; o.Emission = (texCUBE(_CubeMap,IN.worldRefl).rgb*_ReflAmount)*rim; //镜面赋值; o.Specular = _SpecPower; //光泽度赋值; o.Gloss = 1; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
code end -----------------------------------------------------------------------------
最终返回unity,查看效果如下。依然是左侧是我们最新的菲涅尔反射效果:
在上面的实现过程中介绍的比较详细,我们简单的通过一个衰减值,使它来对表面反射量过多或过少的进行调整,通过将视线方向与表面法线相比较,
我们可以计算相机朝向的衰减值。然后我们反转该值来实现一个简单的遮罩效果,这样物体表面的边缘会变得更白,而相机方向的表面也就更黑了。