周复港
周复港

Reputation: 23

Strange jitter and distortion when rendering Tubegeometry of three.js in ArcGIS for JS

I'm new to three.js and I'm using Tubegeometry of three.js in externalRenders of ArcGIS recently. I encountered a problem that the tube will have Strange jitter and distortion when I move the perspective, the situation will be exacerbated as the radius and length of the tube decrease. The gif below should be a good explanation of what happened:

enter image description here

I have been stuck with this for a few days,Can someone help me solve this?

Here's the complete javascript code:

    let path=[
        [116.533079,39.352741],
        [116.533080,39.352753],
    ];
    

    var map = new Map({
        basemap: "satellite",
        ground:'world-elevation'
    });
    var view = new SceneView({
        container: "mapContainer",
        map: map,
        viewingMode: "local",
        camera: {
            position: [116.533079, 39.352741, 13154.641086300715],
            fov: 55,
            heading: 318.70623732061983,
            tilt: 42.34234113203692
        }
    });

    //create the reference line
    view.graphics.add(new Graphic({
        geometry:{
            type:'polyline',
            paths:path,
        },
        symbol:{
            type: "simple-line", // autocasts as SimpleLineSymbol()
            color: [226, 119, 40],
            width: 2
        }
    }))



    const myRenderer = {
        view:view,
        renderer:null, 
        camera:null,    
        scene:null, 
        height:100,
        offset:0,
        map:null,
        setup:function (context){
            this.renderer= new THREE.WebGLRenderer({
                context:context.gl,
                premultipliedAlpha:false,   
            });
            this.renderer.setPixelRatio(window.devicePixelRatio); 
            this.renderer.setViewport(0,0,view.width,view.height);
            this.renderer.autoClearDepth = false; 
            this.renderer.autoClearStencil = false; 
            this.renderer.autoClearColor = false; 

            const originalSetRenderTarget = this.renderer.setRenderTarget.bind(
                this.renderer
            );
            this.renderer.setRenderTarget = function (target) {
                originalSetRenderTarget(target);
                if (target == null) {
                    context.bindRenderTarget();
                }
            };
            this.scene = new THREE.Scene();
            this.camera = new THREE.PerspectiveCamera();

            const axesHelper = new THREE.AxesHelper(10000000);
            this.scene.add(axesHelper);

            

            // create the Tubegeometry
            let v3List=[];
            path.forEach((item)=>{
                var renderPos = [0, 0, 0];
                externalRenderers.toRenderCoordinates(view, [item[0], item[1], 100], 0, SpatialReference.WGS84, renderPos, 0, 1);
                v3List.push(new THREE.Vector3(renderPos[0], renderPos[1], renderPos[2]));
            })
            console.log(v3List)
            let curve = new THREE.CatmullRomCurve3(v3List, false);

            let tubeGeometry = new THREE.TubeBufferGeometry(curve, 1, 10, 20, false);
            var textureLoader = new THREE.TextureLoader();
            this.map = textureLoader.load('img/point2.png')
            this.map.wrapS = THREE.RepeatWrapping;
            this.map.wrapT = THREE.RepeatWrapping;
            this.map.repeat.set(2,20);

            let material = new THREE.MeshBasicMaterial({
                color: 0x85A9A9,
                side:THREE.BackSide,    
                //map:this.map,
                transparent: false,
                depthWrite: false,
                opacity: 0,
                aoMapIntensity:0,
            });
            let tube1 = new THREE.Mesh(tubeGeometry, material);
            this.scene.add(tube1);

            let tubeGeometry2 = new THREE.TubeBufferGeometry(curve, 1, 10, 20, false);
            let tubeMaterial2 = new THREE.MeshPhongMaterial({
                color: 0x85A9A9,
                side:THREE.FrontSide,    
                //map:this.map,
                transparent: false,
                depthWrite: false,
                opacity: 0,
                aoMapIntensity:0,
            });
            let tube2 = new THREE.Mesh(tubeGeometry2, tubeMaterial2);
            console.log(tube2);
            this.scene.add(tube2);

            var ambient = new THREE.AmbientLight(0xffffff, 1);
            ambient.position.set(0, 100, 0);
            this.scene.add(ambient);

            context.resetWebGLState();
        },
        render: function (context) {
            const cam = context.camera;
            this.camera.position.set(cam.eye[0], cam.eye[1], cam.eye[2]);
            this.camera.up.set(cam.up[0], cam.up[1], cam.up[2]);
            this.camera.lookAt(
                new THREE.Vector3(cam.center[0], cam.center[1], cam.center[2])
            );

            this.camera.projectionMatrix.fromArray(cam.projectionMatrix);

            this.map.offset.x += 0.001;
            this.map.needsUpdate = true;

            this.renderer.state.reset();
            this.renderer.render(this.scene, this.camera);

            externalRenderers.requestRender(view);
            // cleanup
            context.resetWebGLState();
        }
    }

    externalRenderers.add(view, myRenderer);
})

Upvotes: 0

Views: 210

Answers (1)

eile
eile

Reputation: 1153

This looks very much like the Precision Issues detailed in https://developers.arcgis.com/javascript/latest/api-reference/esri-views-3d-externalRenderers.html

Upvotes: 1

Related Questions