I’m integrating three js into Cesium. When I create more than 2000 objects via TextureLoader and all my objects are displayed on the screen, I have small fps. How can I optimize the renderer?
Scene creation function and loader:
const createSceneThree = () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const cesium = useCesium();
const threeContainer = document.getElementById("threeContainer");
const threeScene = new Scene();
const threeCamera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 55000000);
const threeRenderer = new WebGLRenderer({ alpha: true, antialias: false, depth: false, powerPreference: "high-performance", precision: 'lowp'});
threeRenderer.setPixelRatio(window.devicePixelRatio)
const threeGltfLoader = new GLTFLoader();
const threeImageLoader = new TextureLoader();
threeRenderer.setSize(window.innerWidth, window.innerHeight);
threeContainer?.appendChild(threeRenderer.domElement);
let scaleFactor = 1;
function updateThreeJS() {
threeCamera.fov = Cesium.Math.toDegrees(cesium.viewer.camera.frustum.fovy);
threeCamera.updateProjectionMatrix();
// Sync Three.js camera with Cesium camera
const cesiumCamera = cesium.viewer.camera;
const cvm = cesiumCamera.viewMatrix;
const civm = cesiumCamera.inverseViewMatrix;
const cameraPosition = Cartesian3.fromElements(civm[12], civm[13], civm[14]);
const cameraDirection = new Cartesian3(-cvm[2], -cvm[6], -cvm[10]);
const cameraUp = new Cartesian3(cvm[1], cvm[5], cvm[9]);
const cameraPositionVec3 = new Vector3(cameraPosition.x, cameraPosition.y, cameraPosition.z);
const cameraDirectionVec3 = new Vector3(cameraDirection.x, cameraDirection.y, cameraDirection.z);
const cameraUpVec3 = new Vector3(cameraUp.x, cameraUp.y, cameraUp.z);
threeCamera.position.copy(cameraPositionVec3);
threeCamera.up.copy(cameraUpVec3);
threeCamera.lookAt(cameraPositionVec3.clone().add(cameraDirectionVec3));
const height = cesium.viewer.camera.positionCartographic.height;
scaleFactor = Math.min(Math.max(height / 2000000, 0.0001), 2.5);
threeScene.children.forEach(child => {
if (child.type === 'Mesh') child.scale.set(scaleFactor, scaleFactor, scaleFactor);
});
threeRenderer.render(threeScene, threeCamera);
}
window.addEventListener('resize', () => {
const width = window.innerWidth;
const height = window.innerHeight;
threeRenderer.setSize(width, height);
threeCamera.aspect = width / height;
threeCamera.updateProjectionMatrix();
});
function renderLoop() {
requestAnimationFrame(renderLoop);
// cesium.viewer.render();
if(threeCamera.position.y < 4000000 && threeScene.children.length > 1) {
threeScene.children.forEach(item => {
item.type === 'Mesh' ? item.visible = !airController._modelThree : item.visible = airController._modelThree
})
}
updateThreeJS();
}
renderLoop();
return {threeScene, threeCamera, threeRenderer, threeGltfLoader, threeImageLoader}
};
export default createSceneThree;
Function for creating objects with an image:
let texture = imageLoader.load(require(`${URLS[item.IVO === 1 ? TVKO_PP : item.TVKO][item.color]}`))
let material = new MeshBasicMaterial({map: texture, transparent: true})
let geometry = new PlaneGeometry(5, 5, 16, 16);
geometry.scale(2000, 2000, 2000)
let planes = new Mesh(geometry, material)
planes.position.set(position.x, position.y, position.z)
planes.quaternion.set(orientation.x, orientation.y, orientation.z, orientation.w)
threeScene.add(planes)