本文将介绍和实现Unity Shader中的玻璃效果。实现效果如下:
一、效果分析和实现原理
试想下生活中的玻璃杯,它能反射周围的环境,同时如果我们将一颗小球放入杯中,我们能够透过玻璃杯看到小球,而且如果玻璃杯表面凹凸不平的话,我们还会看到小球好像被扭曲了,这便是光线在玻璃表面反射和折射的效果。
反射/折射
下面来讲讲在Unity Shader中反射和折射的实现:
反射/折射实现的方法其实很类似,首先获得用于环境映射的立方体纹理,然后通过入射光线的方向和表面法线方向来计算反射方向,再利用反射方向对立方体纹理采样即可。
1.创建用于环境映射的立方体纹理
在Unity 5中,创建用于环境映射的立方体纹理的方法有三种,前两种方法都需要我们提前准备好立方体纹理的图像,然后对其进行一些处理得到Cubemap,这里不做赘述,而着重介绍第三种方法:利用脚本和Unity提供的 Camera.RenderToCubemap 函数来实现,它可以把从任意位置观察到的场景图像存储到6张图像中,从而创建出该位置上对应的立方体纹理,该方法可能根据物体在场景中位置的不同,生成它们各自不同的立方体纹理,因此灵活性较高。
void OnWizardCreate ()
{
//创建用于渲染立方体纹理的的临时摄像机
GameObject go = new GameObject( "CubemapCamera");
go.AddComponent<Camera>();
//将摄像机放置在指定位置
go.transform.position = renderFromPosition.position;
//渲染出立方体纹理
go.GetComponent<Camera>().RenderToCubemap(cubemap);
//销毁临时创建的摄像机
DestroyImmediate( go );
}
2.计算反射/折射方向
CG提供了reflect/refract函数来计算反射/折射方向
观察上图,物体反射到摄像机中的光线方向,可以由光路可逆的原则来反向求得,即
reflDir = reflect(-viewDir, normal);
对于折射方向,