使用three.js/webgl实现简易地形

在cesium等三维地球引擎,是使用Quantized-mesh瓦片来加载地形,但在小场景地图中,我们有更简便的方式来实现简易地形。本篇以mapbox地形瓦片为例,说明在three.js中使用mapbox地形瓦片的方法。

一、获取地形瓦片和影像

        地形瓦片我使用了mapbox的mapbox.terrain-rgb服务,地形影像我使用了mapbox的mapbox_satellite服务,再根据瓦片行列号算法,可以直接获取到具体的地形和影像瓦片。

使用three.js/webgl实现简易地形_第1张图片

 地形瓦片本身是高度图,我们根据其某个点的像素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中顶点的高度进行修改。

四、渲染地形网格

        构建好地形网格后,就可以直接对其进行渲染,这里我设置了两种模式,地形渲染模式和地形贴图模式,都具有实际应用场景。

使用three.js/webgl实现简易地形_第2张图片

地形渲染模式

 使用three.js/webgl实现简易地形_第3张图片

地形+影像模式

 

 

你可能感兴趣的:(webgl,three.js,web3d,three.js,webgl)