Three.js: 无法设置最大和最小缩放级别

Three.js: Unable to Set Maximum and Minimum Zoom Level

我将此示例用于我的 WebGL 全景立方体: https://threejs.org/examples/?q=pano#webgl_panorama_equirectangular

我想在限制范围内放大和缩小,即设置最大和最小缩放级别,但不是代码默认提供的无限。对于无限缩放,如果滚动太多,稍后会反转视图,上面示例中的函数如下所示:

    function onDocumentMouseWheel( event ) {
            camera.fov += event.deltaY * 0.05;
            camera.updateProjectionMatrix();
    }

为了解决这个问题,我尝试在我允许的范围内更新 FOV:

    function onDocumentMouseWheel( event ) {
        var fovMAX = 95;
        var fovMIN = 5;
        var newFov = camera.fov + event.deltaY * 0.05;
        if (newFov > fovMIN && newFov < fovMAX) {
            camera.fov = newFov;
            camera.updateProjectionMatrix();
        };
    }

请注意我的 FOV 是 90:

camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight), 0.1, 100 );

这似乎对最大放大级别非常有效 - 它在 FOV 为 5 时停止并且不会进一步放大。然而,当我缩小到 FOV 95 时,它会停止,但如果我继续用鼠标缩小更多,我会再次无限放大,即使 FOV 仍然是 95。

如何stop/control无限缩小?

您的代码在下面的最小示例中按预期工作。 (我确实做了一个小改动,我使用的是 >=/<= 而不是 >/<。)

var renderer, scene, camera, controls, stats;

var WIDTH = window.innerWidth,
  HEIGHT = window.innerHeight,
  FOV = 35,
  NEAR = 1,
  FAR = 1000;

var fovMax = 95,
  fovMin = 5,
  fovTmp = 0;

function zoom(event) {
  event.preventDefault();
  fovTmp = camera.fov + (event.deltaY * 0.05);
  if (fovTmp >= fovMin && fovTmp <= fovMax) {
    camera.fov = fovTmp;
    camera.updateProjectionMatrix();
  }
}

function init() {
  document.body.style.backgroundColor = "slateGray";

  renderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true
  });

  document.body.appendChild(renderer.domElement);
  document.body.style.overflow = "hidden";
  document.body.style.margin = "0";
  document.body.style.padding = "0";

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
  camera.position.z = 50;
  scene.add(camera);

  var light = new THREE.PointLight(0xffffff, 1, Infinity);
  camera.add(light);

  stats = new Stats();
  stats.domElement.style.position = 'absolute';
  stats.domElement.style.top = '0';
  document.body.appendChild(stats.domElement);

  resize();
  window.onresize = resize;

  // POPULATE EXAMPLE
  var cubeGeo = new THREE.BoxBufferGeometry(1, 1, 1),
    cubeMat = new THREE.MeshPhongMaterial({
      color: "red"
    });
  var mesh = new THREE.Mesh(cubeGeo, cubeMat);
  scene.add(mesh);

  window.addEventListener("wheel", zoom);

  animate();
}

function resize() {
  WIDTH = window.innerWidth;
  HEIGHT = window.innerHeight;
  if (renderer && camera) {
    renderer.setSize(WIDTH, HEIGHT);
    camera.aspect = WIDTH / HEIGHT;
    camera.updateProjectionMatrix();
  }
}

function render() {
  renderer.render(scene, camera);
}

function animate() {
  requestAnimationFrame(animate);
  render();
  stats.update();
}

function threeReady() {
  init();
}

(function() {
  function addScript(url, callback) {
    callback = callback || function() {};
    var script = document.createElement("script");
    script.addEventListener("load", callback);
    script.setAttribute("src", url);
    document.head.appendChild(script);
  }

  addScript("https://threejs.org/build/three.js", function() {
    addScript("https://threejs.org/examples/js/libs/stats.min.js", function() {
      threeReady();
    })
  })
})();

其他原因正在更改您相机的数据。您确定不在任何地方更新 camera.zoom 吗?

就其价值而言,修改 FOV 的唯一其他(核心)three.js 方法是 PerspectiveCamera.setFocalLength

根据新信息进行编辑

啊,这是你的问题。我不知道你用的是外接鼠标控制器。 OrbitControls 不调整 FOV 来创建其缩放效果。相反,它实际上是将相机从控件的 target 移近 to/further。您的放大可能(偶然)对应于它达到 0 距离。但因为它可以缩小到无穷大,所以它继续缩小。

像您评论中那样禁用缩放应该可以解决问题。

three.jsr87