添加水体
loading
与 sky 类似,直接把 threejs 的 water 示例搬过来即可
ts
function initWater() {
const center = map.geo2map(new THREE.Vector3(89.4, 42.7));
const waterGeometry = new THREE.PlaneGeometry(300 * 1000, 300 * 1000);
const water = new Water(waterGeometry, {
textureWidth: 512,
textureHeight: 512,
waterNormals: new THREE.TextureLoader().load("../waternormals.jpg", function (texture) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
}),
sunDirection: new THREE.Vector3(),
sunColor: 0xffffff,
waterColor: 0x001e0f,
distortionScale: 1,
alpha: 1,
});
water.material.transparent = true;
water.material.uniforms["size"].value = 0.1;
water.position.set(center.x, center.y + 5, 200);
const before = water.onBeforeRender;
const after = water.onAfterRender;
water.onBeforeRender = (renderer, scene, camera, geometry, material, group) => {
map.autoUpdate = false;
before.call(water, renderer, scene, camera, geometry, material, group);
};
water.onAfterRender = (renderer, scene, camera, geometry, material, group) => {
map.autoUpdate = true;
after.call(water, renderer, scene, camera, geometry, material, group);
};
map.add(water);
viewer.addEventListener("update", () => {
water.material.uniforms["time"].value += 1.0 / 60.0;
});
return water;
}
TIP
water 模型内部渲染在前会修改 camer 位置做离屛渲染,这会触发地图的 LOD 造成地图抖动,所以需要在 water 渲染前禁止地图更新,渲染后再放开.
TIP
水面与陆地交界有些生硬,我想可以用 threejs 的 FXAA、SAO 等后期缓解,有兴趣的同学可以试试。