【猫猫的Unity Shader之旅】之反光材质

利用天空盒实现简单的反光效果

  现实生活中有许多反射的例子,镜子、平静的水面、光滑的金属表面都有或多或少的反射效果,一种简单的模拟这种现象的做法是利用天空盒和Input结构中的worldRefl变量。

  为了使用天空盒资源,我们可以导入官方的Skyboxes资源包,然后自己创建一个天空盒资源。一个天空盒资源需要六张贴图,分别表示盒子的六个面。

  

  worldRefl表示世界空间中的反射向量,关于这个东西,猫猫目前把它理解成反射过程中的入射光方向,具体的细节还不清楚,有时间会详细研究一下。总之,有了这个向量,我们就可以用texCUBE函数去索引到天空盒上的一个颜色。具体的代码如下:

Shader “Custom/CubeRefl” {Properties {_MainTint (“Main Color”, Color) = (1, 1, 1, 1)_MainTex (“Base (RGB)”, 2D) = “white” {}_CubeMap (“Cube Map”, CUBE) = “”{}_ReflPower(“Refl Power”, Range(0, 1)) = 0.5}SubShader {Tags { “RenderType”=”Opaque” }LOD 200CGPROGRAM#pragma surface surf Lambertsampler2D _MainTex;samplerCUBE _CubeMap;fixed4 _MainTint;fixed _ReflPower;struct Input {float2 uv_MainTex;float3 worldRefl;};void surf (Input IN, inout SurfaceOutput o) {half4 c = tex2D (_MainTex, IN.uv_MainTex);o.Albedo = _MainTint.rgb * c.rgb;o.Emission = texCUBE(_CubeMap, IN.worldRefl).rgb * _ReflPower;o.Alpha = c.a;}ENDCG}FallBack “Diffuse”}

  实现的效果是这样的:

  

  

菲涅尔效果

  咦?这里有奇怪的名字出现哦~

  话说这位菲先生其实是法国的一位物理学家。关于这位老先生的生平事迹这里就不说啦,总之这位菲先生发现了一个有趣的光学现象,所以这个现象就直接叫做菲先生现象啦。这个现象具体指的是:当我们观察物体表面的角度(相对于法线)越大时,看到的反射效果也越明显。

  基于菲先生的结论,,我们可以实现一个这样的Shader,效果也很不错。为了得到观察的方向,我们需要用到Input结构中的另一个变量:viewDir。对上面的代码稍作修改就可以做出菲涅尔效果:

Shader “Custom/CubeRefl” {Properties {_MainTint (“Main Color”, Color) = (1, 1, 1, 1)_MainTex (“Base (RGB)”, 2D) = “white” {}_CubeMap (“Cube Map”, CUBE) = “”{}_ReflPower(“Refl Power”, Range(0, 1)) = 0.5_FresnelPower(“Frensnel Power”, Range(0.1, 5)) = 2}SubShader {Tags { “RenderType”=”Opaque” }LOD 200CGPROGRAM#pragma surface surf Lambertsampler2D _MainTex;samplerCUBE _CubeMap;fixed4 _MainTint;fixed _ReflPower;fixed _FresnelPower;struct Input {float2 uv_MainTex;float3 worldRefl;float3 viewDir;};void surf (Input IN, inout SurfaceOutput o) {half4 c = tex2D (_MainTex, IN.uv_MainTex);fixed diff = 1.0 – saturate(dot(o.Normal, normalize(IN.viewDir)));diff = pow(diff, _FresnelPower);o.Albedo = _MainTint.rgb * c.rgb;o.Emission = texCUBE(_CubeMap, IN.worldRefl).rgb * diff * _ReflPower;o.Alpha = c.a;}ENDCG}FallBack “Diffuse”}

  得到的效果是这样的:

  

  

  话说这位菲先生确实给我们提供了一些思路。用viewDir这个变量,我们可以轻松表示出观察物体表面角度的变化。利用这种变化我们可以实现出很多效果,比如边缘发光,随视角变化的颜色衰减等,如果有足够的想象力,这种方式可以做出很多效果。

结束语

  反射效果可以极大的增强渲染的真实效果,使用天空盒这种方式牺牲的效率也是比较小的,结合上一回说过的利用贴图实现表面不同部分的不同处理,反射也可以做出不同的形式。而viewDir这个东西也给了我们充分的发挥想象力的空间,这里真的要感谢菲先生啦~

启程了,人的智慧才得以发挥。

【猫猫的Unity Shader之旅】之反光材质

相关文章:

你感兴趣的文章:

标签云: