地形网格
一张 140 × 140 的规则网格,顶点沿高度函数抬升,颜色按海拔渐变。 同样的流程可以把 DEM 栅格变成可交互的地形面。
说明
PlaneGeometry(34, 34, 140, 140) 生成一张水平面,随后
rotateX(-Math.PI/2) 把它放倒,顶点的 Y 就成了高度。
遍历 19881 个顶点,按 heightAt(x, z) 写入高程,
再用 computeVertexNormals() 重算法线,光照才会贴着起伏变化。
颜色写在顶点上,材质开启 vertexColors。低处取深绿,中段过渡到黄褐,
高处偏灰白,用 HSL 的色相与明度连续插值实现,比预设几档色带更平滑。
| 设置 | 数值 | 说明 |
|---|---|---|
| 平面尺寸 | 34 × 34 | 场景单位,可理解为 34 米或 34 千米 |
| 分段 | 140 × 140 | 顶点 19881 个,三角面 39200 个 |
| 高度函数 | 两组正弦 + 一峰一谷 | 纯代码生成,不依赖 DEM 文件 |
| 高度夸张 | 0.4 – 2.2 倍 | 只改 scale.y,不重建几何 |
| 材质 | Standard,粗糙度 0.94 | 接近自然地表,几乎没有镜面反射 |
| 相机上限 | 极角 0.495π | 禁止转到地下,避免看到网格背面 |
为什么先放倒再改高度
如果直接在未旋转的平面上改 Z,地形会立起来,像一面墙。把平面绕 X 轴转 −90 度后, 原平面的 Y 方向变成世界的 Z 方向,改顶点的 Y 才是抬升。 这一步顺序不能反,否则法线、纹理坐标与相机朝向都会对不上。
高度夸张的正确做法
示例的夸张滑杆只改网格的 scale.y,几何体不动。
这样切换几乎没有成本,因为顶点缓冲没有重新上传。
但要注意:模型与标注如果与地形同处一个组,会被一起拉伸;
正确做法是把地形放进独立的组,夸张只作用于地形。
在真实项目里,垂直夸张通常设为 1.5 到 3 倍,用于在平面距离远大于高差时突出地形。 如果要做坡度、通视这类量算,必须回到未夸张的真实比例,否则结果没有意义。
换成 DEM 数据
把 heightAt(x, z) 换成从栅格读取的高程即可。需要注意三点:
栅格的行列方向与平面 UV 的对应关系;无效值(如 −9999)要单独处理,不能直接当地形;
高程单位与水平单位要统一,米对米,或千米对千米。
法线不重算,地形会「平」。只改顶点位置而不调用 computeVertexNormals(),
所有法线仍然朝上,光照会均匀铺满整块地形,看起来像一张贴了颜色的纸。