注意点:three.j需要比较低的版本这边使用的是 0.117.1 并且高德的版本需要2.0
首先初始化一个地图
js
// 初始化地图
function initMap() {
AMapLoader.load({
key: 'b8929cd9524f38a88306fcbd0ee0d8de', //首次load必填
version: '2.0',
// 需要使用的的插件列表
plugins: [
'AMap.Geocoder', // 逆向地理解码插件
'AMap.Marker', // 点标记插件
'AMap.MapboxVectorTileLayer', // MVT多面体
'AMap.3DTilesLayer', // MVT多面体
],
})
.then((_AMap) => {
AMap = _AMap
map = new AMap.Map('container', {
viewMode: '3D', // 地图模式
mapStyle: 'amap://styles/grey',
pitch: 55,
zoom: 18,
center: mapCenter,
// 只显示的特征
// features: ['bg', 'road', 'building', 'point'],
features: ['bg', 'road', 'point'],
// layers: [
// // 高德默认标准图层
// new AMap.TileLayer.Satellite(),
// // 楼块图层
// new AMap.Buildings({
// zooms: [16, 18],
// zIndex: 10,
// heightFactor: 0, //2倍于默认高度,3D下有效
// wallColor: 'rgba(0, 0, 0,1)',
// roofColor: 'rgba(89, 142, 213,1)',
// }),
// ],
})
initThree()
})
.catch((e) => {
console.error(e)
})
// var roadNetLayer = new AMap.TileLayer.RoadNet();
// map.add( roadNetLayer);
}
地图加载完之后加载three.js 调用initThree()
js
// 初始化树
function initThree() {
// 初始化数据转换工具 (高德数据转换为three.js坐标数据)
customCoords = map.customCoords
// 数据使用转换工具进行转换,这个操作必须要提前执行(在获取镜头参数 函数之前执行),否则将会获得一个错误信息。
//lngLatToCoord转坐标
comLocation = customCoords.lngLatToCoord(mapCenter)
lightLocation1 = customCoords.lngLatToCoord(lightCenter1)
//灯光二
lightLocation2 = customCoords.lngLatToCoord(klight2)
// 创建webgl layer
let glLayer = new AMap.GLCustomLayer({
// 图层的层级 这里写的太大模型会消失
zIndex: 10,
// 初始化的操作,创建图层过程中执行一次。
init: (gl) => {
render = new THREE.WebGLRenderer({
context: gl,
})
// 自动清空画布这里必须设置为 false,否则地图底图将无法显示
render.autoClear = false
initScene()
initLight()
initCamera()
// 添加盒子 如果不延迟 或者延迟时间少了会保一个警告(Vertex buffer is not big enough for the draw call)
setTimeout(() => {
addBox() // 灯光盒
// addDrone() // 无人机
// addFineDrone() // 无人机动态
addModel()
animate()
}, 500)
},
render: () => {
render.state.reset()
const { near, far, fov, up, lookAt, position } = customCoords.getCameraParams()
camera.near = near
camera.far = far
camera.fov = fov
camera.position.set(...position)
camera.up.set(...up)
camera.lookAt(...lookAt)
camera.updateProjectionMatrix()
render.render(scene, camera)
},
})
map.add(glLayer)
animate()
}
// 初始化场景
function initScene() {
scene = new THREE.Scene()
}
// 初始化相机
function initCamera() {
camera = new THREE.PerspectiveCamera(
60,
mapRef.value.offsetWidth / mapRef.value.offsetHeight,
100,
1 << 30
)
}
// 添加灯光1盒子
function addBox() {
let mat = new THREE.MeshBasicMaterial({
color: 0xffffff,
roughness: 0.5,
metalness: 0.5,
})
let geo = new THREE.BoxBufferGeometry(10, 10, 10)
let mesh = new THREE.Mesh(geo, mat)
mesh.position.set(lightLocation1[0], lightLocation1[1], 20)
scene.add(mesh)
}
// 添加模型
function addModel() {
loader.load('/model/huanglong3d/huanglongModel.gltf', function (gltf) {
//GLTF在场景中的位置
gltf.scene.position.set(comLocation[0], comLocation[1], 0)
//缩放模型
gltf.scene.scale.set(0.5, 0.5, 0.5)
//旋转
gltf.scene.rotation.x = 0.5 * Math.PI
// gltf.scene.rotation.y = 1000;
scene.add(gltf.scene)
// models.start = gltf.scene
gltf.scene.traverse(function (child) {
if (child.isMesh) {
//模型阴影
// child.castshadow = true
//调整金蜀度
// child.material.metalness = 0.58
//模型变亮 模型自发光
// child.material.emissive = child.material.color
// child.material.emissiveMap = child.material.map
//模型变亮,或重新赋颜色
// child.material.color.set(0x5186cc)
}
})
})
}
// 动画
function animate() {
// 渲染时刷新地图
map.render()
// 自动刷新
requestAnimationFrame(animate)
}
// 初始化光源
function initLight() {
// 创建环境光
let light = new THREE.AmbientLight(0x03378f, 1)
// let light = new THREE.AmbientLight(0xfc5531, 100)
light.position.set(comLocation[0], comLocation[1], 25) //点光源位置
light.position.set(0, 0, 0) //点光源位置
//添加环境光
scene.add(light)
// 点光1
let pointLight = new THREE.PointLight(0xffce66, 1)
pointLight.position.set(lightLocation1[0], lightLocation1[1], 20)
pointLight.distance = 420 // 设置光源距离
// 点光2
let pointLight2 = new THREE.PointLight(0xffce66, 1)
pointLight2.position.set(lightLocation2[0], lightLocation2[1], 80)
pointLight2.distance = 400 // 设置光源距离
// pointLight.castShadow = true
// pointLight.shadow.camera.near = 0.1
// pointLight.shadow.camera.far = 25
// 灯光朝向
// pointLight.lookAt(new THREE.Vector3(0, 0, 0));
const pointLightHelper = new THREE.PointLightHelper(pointLight16, 100) //添加 点光源的辅助线
scene.add(pointLight)
scene.add(pointLightHelper)
scene.add(pointLight2)
}