三个JS:OrbitControls拖拽时图片像素跳跃

Three JS: OrbitControls the pixel of picture jumps when dragging

我最近开始处理3d,我想在场景中移动,但是拖动时,我看到图片中的像素如何在相机停止移动之前开始跳跃。这显然是错误的工作

为什么会这样?以及如何避免呢? 我的代码:https://codepen.io/davedev13/pen/zYEyxRX

const data = {
    "objects": [
        {
            "img": "https://picsum.photos/400/500",
            "title": "Creative",
            "description": "lorem ipsum",
            "url": "/1",
            "position": {
                "left": "-500",
                "top": "500"
            }
        },
        {
            "img": "https://picsum.photos/400/500",
            "title": "Angles",
            "description": "lorem ipsum",
            "url": "/2",
            "position": {
                "left": "500",
                "top": "-500"
            }
        },
        {
            "img": "https://picsum.photos/400/500",
            "title": "Awwards",
            "description": "lorem ipsum",
            "url": "/3",
            "position": {
                "left": "500",
                "top": "0"
            }
        },
        {
            "img": "https://picsum.photos/400/500",
            "title": "Conexe",
            "description": "lorem ipsum",
            "url": "/4",
            "position": {
                "left": "0",
                "top": "500"
            }
        },
        {
            "img": "https://picsum.photos/400/500",
            "title": "Luxury",
            "description": "lorem ipsum",
            "url": "/5",
            "position": {
                "left": "-500",
                "top": "0"
            }
        },
        {
            "img": "https://picsum.photos/400/500",
            "title": "Develop",
            "description": "lorem ipsum",
            "url": "/6",
            "position": {
                "left": "0",
                "top": "-500"
            }
        },
        {
            "img": "https://picsum.photos/400/500",
            "title": "Desing",
            "description": "lorem ipsum",
            "url": "/7",
            "position": {
                "left": "500",
                "top": "500"
            }
        },
        {
            "img": "https://picsum.photos/400/500",
            "title": "Sociality",
            "description": "lorem ipsum",
            "url": "/8",
            "position": {
                "left": "-500",
                "top": "-500"
            }
        }
    ]
}

class Drag {
    drag = {
        width: 2560,
        height: 1440,
    };
    mouseOut = false;

    constructor(container) {
        this.container = container;
        let w = container.clientWidth;
        let h = container.clientHeight;
        let viewSize = h;
        let aspectRatio = w / h;

        this.viewport = {
            viewSize: viewSize,
            aspectRatio: aspectRatio,
            left: (-aspectRatio * viewSize) / 2,
            right: (aspectRatio * viewSize) / 2,
            top: viewSize / 2,
            bottom: -viewSize / 2,
            near: -10,
            far: 100
        }

        this.initScene();
    }

    initScene() {
        this.camera = new THREE.OrthographicCamera(
            this.viewport.left, this.viewport.right,
            this.viewport.top, this.viewport.bottom,
            this.viewport.near, this.viewport.far
        );

        this.scene = new THREE.Scene();

        this.renderer = new THREE.WebGLRenderer({
            // alpha: true // чтобы сцена была прозрачной
        });

        this.renderer.domElement.id = 'canvasGrid';
        this.renderer.setPixelRatio(window.devicePixelRatio);
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.renderer.setClearColor(0xdcdcdc, 1);

        this.container.appendChild(this.renderer.domElement);

        // драг контейнер для сцены
        const geometry = new THREE.PlaneGeometry(this.drag.width, this.drag.height);
        const material = new THREE.MeshBasicMaterial({
            color: 0xdcdcdc,
        });
        this.drag.plane = new THREE.Mesh(geometry, material);

        // драг бокс по которому гранимац которого будет двигаться сцена при драге
        this.dragBox = new THREE.Box3().setFromObject(this.drag.plane);

        this.scene.add(this.drag.plane);

        this.sceneObjects();
        this.setControls();
        this.animate();

        window.addEventListener('mouseout', () => this.mouseOut = true, false);
        window.addEventListener('mouseover', () => {
            this.mouseOut = false;
            this.animate();
        }, false);
    }



    sceneObjects() {
        // instantiate a loader
        const loader = new THREE.TextureLoader();

        data.objects.map((item) => {
            const group = new THREE.Group();
            group.name = item.title;

            // load a resource
            loader.load(
                // resource URL
                item.img,
                // onLoad callback
                function (texture) {
                    const width = texture.image.naturalWidth * 0.5;
                    const height = texture.image.naturalHeight * 0.5;

                    // in this example we create the material when the texture is loaded
                    const geometry = new THREE.BoxGeometry(width, height, 0);
                    const material = new THREE.MeshBasicMaterial({map: texture});
                    const mesh = new THREE.Mesh(geometry, material);

                    group.add(mesh);
                    group.position.set(item.position.left, item.position.top, 0);
                },

                // onProgress callback currently not supported
                undefined,

                // onError callback
                function (err) {
                    console.error('An error happened.', err);
                }
            );

            this.scene.add(group);
        });

        const geometry1 = new THREE.BoxGeometry(550, 300, 0);
        const texture = new THREE.TextureLoader().load("https://miro.medium.com/max/1400/1*Ynit7J26tXLwyq-sB3AUug.png");
        console.log(texture)
        const material1 = new THREE.MeshBasicMaterial({map: texture, opacity: 0.3});
        const mesh = new THREE.Mesh(geometry1, material1);
        this.scene.add(mesh);
    }

    render() {
        // if (this.mouseDownPressed) {
        let x1 = this.camera.position.x + (this.camera.left / this.camera.zoom);
        let x1a = Math.max(x1, this.dragBox.min.x);
        let pos_x = x1a - (this.camera.left / this.camera.zoom);

        let x2 = pos_x + (this.camera.right / this.camera.zoom);
        let x2a = Math.min(x2, this.dragBox.max.x);
        pos_x = x2a - (this.camera.right / this.camera.zoom);

        let y1 = this.camera.position.y + (this.camera.bottom / this.camera.zoom);
        let y1a = Math.max(y1, this.dragBox.min.y);
        let pos_y = y1a - (this.camera.bottom / this.camera.zoom);

        let y2 = pos_y + (this.camera.top / this.camera.zoom);
        let y2a = Math.min(y2, this.dragBox.max.y);
        pos_y = y2a - (this.camera.top / this.camera.zoom);

        this.camera.position.set(pos_x, pos_y, this.camera.position.z);
        this.camera.lookAt(pos_x, pos_y, this.controls.target.z); // todo: what is it?
        this.controls.target.set(pos_x, pos_y, 0);
        this.controls.update();
        // }

        this.renderer.render(this.scene, this.camera);
    }

    setControls() {
        // Need to be similar to what is in OrbitControls3Dpane.js constructor
        this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
        this.controls.mouseButtons = {
            LEFT: THREE.MOUSE.PAN,
            MIDDLE: THREE.MOUSE.DOLLY,
            RIGHT: THREE.MOUSE.PAN
        }
        //////////////////////////////////////
        // Set rotate related parameters
        //////////////////////////////////////
        // No rotation.
        this.controls.enableRotate = false;
        this.controls.minPolarAngle = Math.PI / 2;
        this.controls.maxPolarAngle = Math.PI / 2;
        // No orbit horizontally.
        this.controls.minAzimuthAngle = 0; // radians
        this.controls.maxAzimuthAngle = 0; // radians


        //////////////////////////////////////
        // Set zoom related parameters
        //////////////////////////////////////
        this.controls.enableZoom = true;
        this.controls.zoomSpeed = 0.9;
        this.controls.minDistance = this.camera.near;
        this.controls.maxDistance = this.camera.far;
        this.controls.minZoom = window.innerWidth > window.innerHeight ?
            window.innerWidth / this.drag.width : window.innerHeight / this.drag.height;
        this.controls.maxZoom = 1 + this.controls.minZoom;

        //////////////////////////////////////
        // Set pan related parameters
        //////////////////////////////////////
        this.controls.enablePan = true;
        this.controls.panSpeed = 0.6;
        this.controls.screenSpacePanning = true;
        this.controls.enableDamping = true;

        // this.renderer.domElement.addEventListener('mousedown', () => {
        //  this.mouseDownPressed = true;
        // }, false);

        // this.renderer.domElement.addEventListener('mouseup', () => {
        //  setTimeout(() => {
        //      this.mouseDownPressed = false;
        //  }, 700);
        // }, false);
    }

    animate() {
        this.render();

        if (!this.mouseOut) {
            requestAnimationFrame(this.animate.bind(this));
        }
    }
}

function init() {
    new Drag(document.querySelector('.canvas'));
}

init();
.canvas {
  width: 100vw;
  height: 100vh;
}
<!-- partial:index.partial.html -->
<div class="canvas"></div>
<!-- partial -->
  <script src='https://threejs.org/build/three.js'></script>
<script src='https://threejs.org/examples/js/controls/OrbitControls.js'></script><script  src="./script.js"></script>

我使用“OrthographicCamera”创建了一个场景,并将此相机与 OrbitControls 一起移动,也许这对我来说不是最佳选择,如果是这样 - 请告诉我如何正确操作?

antialias:真正在 WebGLRenderer 解决

所有相同的设置,场景立即变得更流畅,图片没有错误

也就是他降低性能滑出...