原帖:https://blog.youkuaiyun.com/zhishiqu/article/details/79077883
跟着原贴做了一下three和cesium 的结合,代码稍微改动了点,记录一下。完整代码附在最后。
思路:
1.要把cesiumjs和threejs的场景同时显示,所以需要创建两个容器,分别用于显示cesium的场景和three的场景,两个场景要重合;
2.将cesium和three的渲染频率调成一致;
3.将cesium和three的相机位置角度等调成一致。
4.将three里的图形位置调整为在地球表面
具体实现:
1.初始化cesium
cesium初始化时,要将它的自动渲染关掉(即useDefaultRenderLoop属性调整为false)
cesium.viewer = new Cesium.Viewer("cesiumContainer", {
useDefaultRenderLoop: false, //关闭自动渲染
selectionIndicator: false,
homeButton: false,
sceneModePicker: false,
navigationHelpButton: false,
animate: false,
timeline: false,
fullscreenButton: false,
navigationInstructionsInitiallyVisible: false,
allowTextureFilterAnisotropic: false,
contextOptions: {
webgl: {
alpha: false,
antialias: true,
preserveDrawingBuffer: true,
failIfMajorPerformanceCaveat: false,
depth: true,
stencil: false,
anialias: false
}
},
targetFrameRate: 60,
resolutionScale: 0.1,
orderIndependentTranslucency: true,
// creditContainer:"CreditDisplay",
// imageeryProvider: googlemap, //谷歌地图
baseLayerPicker: true,
geocoder: false,
automaticallyTrackDataSourceClocks: false,
dataSources: null,
clock: null,
terrainShadows: Cesium.ShadowMode.DISABLED
});
2.初始化three
let fov = 45;
let width = window.innerWidth;
let height = window.innerHeight;
let aspect = width / height;
let near = 1;
let far = 10 * 1000 * 1000; // needs to be far to support Cesium's world-scale rendering
three.scene = new THREE.Scene();
three.camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
three.renderer = new THREE.WebGLRenderer({ alpha: true });
// let axis=new THREE.AxesHelper(1000*1000*1000);
// three.scene.add(axis);
ThreeContainer.appendChild(three.renderer.domElement);
3.调整three和cesium的渲染频率
手动开启cesium和three的渲染,并放进一个渲染频率里。
function loop() {
requestAnimationFrame(loop);
renderCesium(); //渲染cesium
renderThree(); //渲染three
}
function renderCesium() {
cesium.viewer.render();
}
function renderThree() {
var width = ThreeContainer.clientWidth;
var height = ThreeContainer.clientHeight;
three.renderer.setSize(width, height);
three.renderer.render(three.scene, three.camera);
}
4.调整相机一致
这里使用的cesium的相机为主相机,使three的相机与cesium保持一致即可。
由于相机的位置一直在变换,所以讲相机位置调整放进每一帧的渲染中。
function renderCamera(){
// register Three.js scene with Cesium
three.camera.fov = Cesium.Math.toDegrees(cesium.viewer.camera.frustum.fovy) // ThreeJS FOV is vertical
three.camera.updateProjectionMatrix();
// Clone Cesium Camera projection position so the
// Three.js Object will appear to be at the same place as above the Cesium Globe
three.camera.matrixAutoUpdate = false;
var cvm = cesium.viewer.camera.viewMatrix;
var civm = cesium.viewer.camera.inverseViewMatrix;
three.camera.matrixWorld.set(
civm[0], civm[4], civm[8], civm[12],
civm[1], civm[5], civm[9], civm[13],
civm[2], civm[6], civm[10], civm[14],
civm[3], civm[7], civm[11], civm[15]
);
three.camera.matrixWorldInverse.set(
cvm[0], cvm[4], cvm[8], cvm[12],
cvm[1], cvm[5], cvm[9], cvm[13],
cvm[2], cvm[6], cvm[10], cvm[14],
cvm[3], cvm[7], cvm[11], cvm[15]
);
three.camera.lookAt(new THREE.Vector3(0, 0, 0));
var width = ThreeContainer.clientWidth;
va