Cesium高阶学习七、反射水面

一、简介
反射水面的原理是根据当前相机计算出反射相机,利用反射相机进行离屏渲染,将渲染的结果作为纹理贴合到水面几何,并加入一些噪声使其更加逼真。
在这里插入图片描述

离屏渲染相关的知识已在“离屏渲染”章节介绍过,这里主要的难点是计算反射相机,计算反射相机的方法也很多,这里介绍一个利用反射向量计算的方法。反射向量计算方法的原理: 计算从当前相机位置指向水面中心 O 的向量 V 和距离 D,根据向量 V 和水面法线 N 计算反射向量 R。此时反射相机的位置为:O - D * R,视线方向和上方向可以同理可得。
在这里插入图片描述

二、计算反射相机

1、假定水面点位数组如下:

let positions = [
     [-75.59674, 40.03768, 80],
     [-75.59691, 40.03795, 80],
     [-75.59697, 40.03802, 80],
     [-75.5972, 40.03794, 80],
     [-75.5974, 40.03796, 80],
     [-75.59767, 40.03789, 80],
     [-75.5979, 40.03779, 80],
     [-75.59805, 40.03769, 80],
     [-75.59806, 40.03758, 80],
     [-75.598, 40.03734, 80],
     [-75.59789, 40.0372, 80],
     [-75.59772, 40.03717, 80],
     [-75.59745, 40.03728, 80],
     [-75.59716, 40.0374, 80],
     [-75.59693, 40.0375, 80],
     [-75.59677, 40.03756, 80],
     [-75.59662, 40.03761, 80]
 ];
positions = Cesium.Cartesian3.fromDegreesArrayHeights([].concat.apply([], positions));//经纬度转为笛卡尔

2、将其添加到场景中

viewer.entities.add({
   
    polygon: {
   
        hierarchy: new Cesium.PolygonHierarchy(positions),
        perPositionHeight: true,
        material: Cesium.Color.WITHE
    }
})

在这里插入图片描述

3、 求取水面法线:水面法线即为平面的法线,可以用平面中心的法线代替

let n = positions.length;
let a = new Cesium.Cartesian3();
positions.forEach(p => {
    
    a = Cesium.Cartesian3.add(a, p, a);
})
a = Cesium.Cartesian3.multiplyByScalar(a, 1 / n, a);//中心点
//获取中心点的法线
let normal= Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(a);
console.log(normal);

在这里插入图片描述

4、计算反射相机的位置

a、首先获取场景相机到水面中心点的向量
 //场景相机到水面中心点的向量
 let V=Cesium.Cartesian3.sub(centerPosition,viewer.camera.positionWC,new Cesium.Cartesian3());
b、然后根据水面法线计算反射后的向量
//计算向量V通过法线反射后的向量R
 n = Cesium.Cartesian3.dot(normal, V);
 let t = Cesium.Cartesian3.multiplyByScalar(normal, 2 * n, new Cesium.Cartesian3());
 let R = Cesium.Cartesian3.subtract(V, t, new Cesium.Cartesian3());

根据法线计算反射向量的公式为:

float3 reflect( float3 i, float3 n ){
   
	return i - 2.0 n dot(n,i);
}
c、然后对反射向量进行取反即可得到反射相机的向量
 //对R进行取反即为反射相机的向量
 R = Cesium.Cartesian3.negate(R, R);
d、然后计算反射相机的位置
//此时反射相机的坐标为
 let reflectCameraPosition = Cesium.Cartesian3.add(centerPosition, R, new Cesium.Cartesian3());

5、计算反射相机的方向:反射相机的方向即为最开始的R向量的归一化向量

//计算反射相机的方向
 let reflectCameraDirection = Cesium.Cartesian3.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cesium进阶学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值