Cesium中实现水面反射
水面反射的核心是计算反射相机,并利用反射相机渲染水面纹理。
反射相机计算
反射相机是一个与当前相机相对于水面,呈镜面对称的相机。
定义一个相机需要定义至少三个量:位置,视线方向和上方向。
反射相机的计算有很多方式,这里简单举例两种:
利用点到平面距离计算
计算当前相机位置到水面的最短距离 L ,沿着水面法线方向的反方向,将相机位置平移 2L,即可得到反射相机的位置。
视线方向和上方向可以同理可得。
利用反射向量计算
计算从当前相机位置指向水面中心 O 的向量 V 和距离 D,根据向量 V 和水面法线 N 计算反射向量 R。此时反射相机的位置为:O - D * R。
视线方向和上方向可以同理可得。
利用反射相机渲染场景
利用创建好的反射相机渲染场景到 Framebuffer 中,这里涉及到的方法为离屏渲染。
值得注意的是,这里如果直接使用反射相机渲染场景,最终实现出来的倒影会包含水面底下的东西,在现实生活中,这是不科学的。
因此需要修改反射相机的投影矩阵,并利用新的投影矩阵渲染场景。新的投影矩阵计算方式可以参考 ThreeJS 。


绘制水面
把反射纹理作为水面网格的纹理,渲染水面网格。
计算水面网格的纹理寻址时,先把水面网格中的点投影到屏幕空间,根据屏幕空间坐标确定纹理寻址
并利用法线贴图对水面的法线进行扰动,实现水面的波动效果。
最后加入菲涅尔反射计算即可大致实现一个水面反射(更丰富的效果还需加入折射和水深等计算)。
最终效果
Cesium中实现水面反射
https://www.liaomz.top/2022/07/27/cesium-zhong-shi-xian-shui-mian-fan-she/