菲涅尔效应是什么?
理解菲涅尔效应,你首先得知道在自然界中会发生反射和折射,而菲涅尔就是描述反射/折射与视点角度之间的关系。
举一个例子,假设有一个十分平静的水面,当你垂直看向水面的时候,反射是最强的,折射是最弱的,当年倾斜45度的时候,你能既能看到水下面的东西和天空的颜色,因为这时候反射和折射同时存在。

如何计算菲涅尔效应?
Schlick菲涅尔近似等式:
其中是为法线入射时的反射率(通常取 0.04),
分别为法向向量和观察角view向量
得出来的是反射率。
Empricial菲涅而近似等式
其中bias和scale,power都是控制项代表偏移,缩放,强度。
同上
Shader代码实现(Unity)
这里我们用简单一点的Schlick菲涅尔等式实现。
我们要知道光线发生菲涅尔现象之后如何传播,很显然一部分发生反射沿着一定角度弹回去,一部分发生折射现象。
那么折射的光去哪里了?首先你要知道折射现象能发生在任何物体上,包括不透明物体。
非金属不透明物体:折射光被吸收,通过物体内部粒子散射最后形成漫反射的效果。
金属不透明物体:折射光被物体内部粒子几乎全部吸收,没有漫反射,只有表面反射。
半透明材质:和非金属不透明物体差不多最终都是呈现漫反射效果
透明材质:折射光全部透过物体,发生透视。
这里我们只实现最基本的不透明漫反射。
这时候我们可以知道我们实现这些效果就需要计算慢反射,菲涅尔的反射部分,和环境光的影响。
1 | Shader "Unlit/Fresnel" |
详细讲解部分
fixed3 color = ambient + lerp(diffuse,reflection,saturate(fresnel))*atten;
为什么呢采用lerp插值计算盒saturate将值限制在 0 到 1 之间?
lerp 是线性插值函数,公式为:a + (b - a) * t
a = diffuse(漫反射颜色)
b = reflection(反射颜色)
t = saturate(fresnel)(插值因子)
lerp效果渐变过渡,自然真实,saturate确保插值因子始终在有效范围内。
fixed3 reflection = texCUBE(_Cubemap,i.worldrefl).rgb;
如何采样的?从立方体贴图中按照 i.worldrefl 方向,采样出该方向看到的颜色。
差不多如图示的意思但是这里的坐标系只是方便理解真实情况不是这样的。

说些什么吧!