MapboxGL Render Function Issue

Viewed 209

I'm using mapboxgl and I'm also using ThreeJS be able to import 3D model to the scene. The 3D model that I used has very high polygon count. Due to MapboxGl's render function triggering in each frame my browser is being very laggy. Is it possible to trigger the render function only once or which function must use at this point istead of render function ? I would like to render my 3D model only once on the map.

Here is my codes:

mapBoxGLSetup: function () {
        mapboxgl.accessToken = "";
        oOriginPoint = [29.400261610397465, 40.87692013157027, 1];
        oMap = new mapboxgl.Map({
            logoPosition: "bottom-right",
            container: oSceneContainer.id,
            style: 'mapbox://styles/mapbox/streets-v11',
            center: oOriginPoint,
            zoom: 15,
            pitch: 0,
            antialias: true
        });
        var modelOrigin = oOriginPoint;
        var modelAltitude = 0;
        var modelRotate = [Math.PI / 2, Math.PI / 6.5, 0];
        var modelAsMercatorCoordinate = mapboxgl.MercatorCoordinate.fromLngLat(
            modelOrigin,
            modelAltitude
        );
        o3DModelTransform = {
            translateX: modelAsMercatorCoordinate.x,
            translateY: modelAsMercatorCoordinate.y,
            translateZ: modelAsMercatorCoordinate.z,
            rotateX: modelRotate[0],
            rotateY: modelRotate[1],
            rotateZ: modelRotate[2],
            scale: (modelAsMercatorCoordinate.meterInMercatorCoordinateUnits() / 1000) * 0.85
        };
    },
oSceneMapSetup: function () {
        oMap.on('style.load', function () {
            oMap.addLayer({
                id: 'custom_layer',
                type: 'custom',
                renderingMode: '3d',
                onAdd: function (oMapElement, oGlElement) {
                    base.oMapElement = oMapElement;
                    base.setupRenderer(oMapElement, oGlElement);
                    base.setupLayout(); // I'm loading 3D model in this function
                    base.setupRayCaster();
                },
                render: function (gl, matrix) {
                    // This render function is triggering each frame
                    var rotationX = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(1, 0, 0), o3DModelTransform.rotateX);
                    var rotationY = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 1, 0), o3DModelTransform.rotateY);
                    var rotationZ = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 0, 1), o3DModelTransform.rotateZ);
                    var oMatrix = new THREE.Matrix4().fromArray(matrix);
                    var oTranslation = new THREE.Matrix4().makeTranslation(o3DModelTransform.translateX, o3DModelTransform.translateY, o3DModelTransform.translateZ)
                        .scale(new THREE.Vector3(o3DModelTransform.scale, -o3DModelTransform.scale, o3DModelTransform.scale))
                        .multiply(rotationX)
                        .multiply(rotationY)
                        .multiply(rotationZ);
                    oCamera.projectionMatrix = oMatrix.multiply(oTranslation);
                    oRenderer.resetState();
                    oRenderer.render(oScene, oCamera);
                    base.oMapElement.triggerRepaint();
                }
            })
        });
    },

Thanks for your help and support.

1 Answers

As long as you still calling triggerRepaint on each layer render loop, you will repaint the full map, it’s inherent to the way CustomLayerInterface and update layer work in Mapbox.

When I did my first research on the TriggerRepaint topic, I found a quite old issue in Mapbox where a guy tested all the different options, including having a fully separated context and even 2 mapbox instances, one of them empty. Here is the link

The performance was obviously better in terms of FPS/memory, but there were other collaterals that I personally wouldn't assume for threebox, like losing the depth calculation between mapbox fill-extrusions and 3D custom layer.

Sharing context Different contexts & canvas
image image

The second issue is the delay between the movement of both cameras. While current sharing context ensures the objects are fixed and stuck to a coords set, creating different contexts will produce a soft dragging effect where the delay between the 2 contexts render can be visually perceived when the map moves first and the 3D objects follow. It's perceivable even with ne single cube, so with thousands of objects will be definitely clearer.
3contexts

Related