用途:为 Three.js 场景搭建一个实时风景背景,让主体看起来身处某个环境,同时不喧宾夺主。资料建议叠加 threejs-weather 添加雨雪风暴,主体为建筑时配合 threejs-towers。
主要能力与做法:
- 地形网格:不用方形高度场,而在相机下方用极坐标网格采样,径向环随距离变疏(pow(t, 2.4)),使每环覆盖大致相同的屏幕像素;注意四边形绕序,索引为 (a0, b1, b0, a0, a1, b1),否则会从地下看到天空。
- 高度函数:先做域扭曲再叠加八度,landH 中先用 fbm 扭曲采样位置,再叠加宽地形与脊线;草地、石块、雾等散布物必须采样同一 landH。脊线振幅需随距离放大,否则远处地平线会变平。
- 着色:按地形自身属性计算顶点色(坡度、湿度),而非平铺贴图,可避免接缝;再叠加极低频噪声防止色带。
- 草地:约 10 万根草用单个 InstancedMesh 的五段带状几何,弯曲、倾斜、锥化与阵风全在顶点着色器完成;草地场锚定相机并吸附到单元格,避免边缘与背后开销。注意不要在片元着色器硬编码草色,否则材质颜色无法改变它,需为混色单独设 uniform。
- 石块:用坡度做拒绝采样散布,setMatrixAt 到 InstancedMesh,压扁并下沉使其像嵌入地面。
- 天空:在 8×512 画布上画六段垂直渐变,映射到背面球体,可每帧重绘;地平线色标略低于几何地平线,使雾色与天空衔接无痕。
- 星空:把星点限制在相机可达的高度带内,用三种尺寸类别,按 devicePixelRatio 缩放点大小,加性混合、sizeAttenuation: false、fog: false、depthWrite: false;约 3.9 万点。
- 昼夜:把每个时段存为完整状态(太阳位置与颜色、半球光、环境光、补光、轮廓光、雾色与范围、地面、草地、六段天空色、阴影强度、星星不透明度),在两者间插值;过渡中切换时把当前插值状态冻结为新起点,避免跳变。天气作为乘数叠加,而非新增预设。
检查项:绕到地平线下方看是否透地;看最远环是否平坦;连续两次在过渡中切换时段是否跳变;在视网膜屏检查;关注 draw call 数而非三角形数。
限制:资料未提供安装命令、依赖版本、许可与收费信息,暂未提供。