Map 地图
mini map 场景小地图的添加
制作场景小地图,意味着除了渲染scene和主视角控制的camera外,
还会用到一个小地图专用的摄像机。
这里的conrtols控制器使用 MapControls 会更好,
MapControls 控制摄像机的方式偏向 鸟瞰视角
1 | import {MapControls} from "three/examples/jsm/controls/MapControls"; |
创建一个新的dom容器,用于渲染小地图:
1 | <style> |
为小地图准备专门的 渲染器 、 摄像机
1 | const miniMapDom = document.getElementById('mini-map') |
1 | const miniMapCamera = new THREE.PerspectiveCamera( |
1 | function miniMapAnimation(){ |
视角联动
通过raycaster获取鼠标在小地图上的点击位置P,
将大地图的相机位置移动到P处,
注意相机位置移动后,还需要修改controls.target才能修改相机的朝向
1 | const mousePosition = new THREE.Vector2() |
texture + layer 控制实现小地图
小地图一般不需要过于精细的渲染,
因此为这个功能专门渲染一个模型,会消耗很多性能,
因此可以直接用一张texture纹理图片代替模型:
1 | const textureLoader = new THREE.TextureLoader() |
通过图层控制的方式,将小地图用到的texture和实际的model分开到两个图层,
小地图渲染器只对texture图层进行渲染,
但是仍能保留raycaster交互事件:
1 | miniMapCamera.layers.disableAll() |
在小地图中标注场景物体位置
在场景中动态添加建筑物,通过raycaster能够获得物体坐标,
在小地图的同坐标位置创建图标(贴图平面),
需要注意的是,小地图图标需要和小地图在同一个图层:
1 | // 加载tower icon |
DLC1:塔楼添加shader雷达效果
用shader和一张灰度转场图实现,
需要注意的是,叠加在同一y轴的物体会出现深度冲突的问题,
因此需要给y轴一定的偏移:
Math.random() * 0.01
1 | <script type="x-vertex" id="v-shader"> |
1 | // 渐变材质 |
DLC2:CSS2DRender
引入CSS2DRender实现通过input:range控制扫描圈的大小
1 | const labelRenderer = new CSS2DRenderer() |
小地图显示动态物体
小地图上物体图标的变化和实际物体的变化原理完全一致,
下面代码实现一台低空飞行的直升飞机:
1 | // 加载直升飞机 |
这辆直升飞机有固定的航迹,使用CatmullRomCurve3创建:
1 | const points = [ |
此外,还需要在小地图中创建一个直升飞机对应的icon:
1 | const helicopterIconMat = new THREE.ShaderMaterial({ |
icon使用shaderMaterial自定义波纹效果:
1 | <script type="x-fragment" id="f-shader-2"> |
在动画帧中改变直升飞机和飞机图标的position和切向量
1 | const clock = new THREE.Clock() |