使用three.js/webgl实现简易地形
·
在cesium等三维地球引擎,是使用Quantized-mesh瓦片来加载地形,但在小场景地图中,我们有更简便的方式来实现简易地形。本篇以mapbox地形瓦片为例,说明在three.js中使用mapbox地形瓦片的方法。
一、获取地形瓦片和影像
地形瓦片我使用了mapbox的mapbox.terrain-rgb服务,地形影像我使用了mapbox的mapbox_satellite服务,再根据瓦片行列号算法,可以直接获取到具体的地形和影像瓦片。
地形瓦片本身是高度图,我们根据其某个点的像素rgb值,就可以计算出这个点的高程。
terrainHeight = -10000.0 + ((r * 256.0 * 256.0 * 256.0 + r * 256.0 * 256.0 + b * 256.0) * 0.1)"
二、地形网格构建
地形瓦片有确切的地理范围,因此构建地形网格时,我们直接构建宽高为瓦片地理宽高的Plane,再根据实际的地形精度需求,对Plane进行细分。
let planeGeometry = new THREE.PlaneGeometry(width, height, density, density);
三、从地形瓦片中获取网格顶点高度
关于从地形瓦片中获取高度,我尝试了两种方式,第一种是使用自定义着色器,在顶点着色器中对地形瓦片进行采样,并根据采样结果对顶点高度进行计算,这个好处是计算全部在着色器中进行,高效,但是缺点是片元的法向量计算以及三角面拾取会存在问题。
vertexShader: " varying vec2 v_uv;" +
" uniform sampler2D u_terrainRGB;" +
" void main() {" +
" vec4 finalPosition = vec4(position, 1.0);" +
" vec4 terrainPixel = texture2D(u_terrainRGB, uv);"+
" float terrainHeight = -10000.0 + ((terrainPixel.x*256.0* 256.0 * 256.0 + terrainPixel.y * 256.0 * 256.0 + terrainPixel.z*256.0) * 0.1);"+
" finalPosition.z += terrainHeight;"+
" v_uv = uv;" +
" gl_Position = projectionMatrix * modelViewMatrix * finalPosition;" +
" }",
第二种方式是,遍历Plane几何中每个顶点,根据位置从地形瓦片中采样并计算出高度值,直接对Plane中顶点的高度进行修改。
四、渲染地形网格
构建好地形网格后,就可以直接对其进行渲染,这里我设置了两种模式,地形渲染模式和地形贴图模式,都具有实际应用场景。
地形渲染模式
地形+影像模式
更多推荐
已为社区贡献9条内容
所有评论(0)