You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Three.js平面几何体尺寸不随渲染器/屏幕尺寸变化

Fixing Three.js Plane Geometry Size That Changes With Screen/Renderer Dimensions

Let's break down why your plane's size is shifting and fix it step by step.

Root Cause

Your core issue is a mismatch between how you calculate the orthographic camera's viewport and the actual size of your renderer. You're setting the renderer to only take up half the window (renderer.setSize( width / 2, height / 2 )), but your camera's aspect ratio is calculated using the full window dimensions instead of the renderer's actual size. This misalignment makes the plane appear to scale when the screen resizes, even if you set a fixed geometry size.

Solution: Align Camera Calculations to Renderer Size

We need to tie all camera aspect and viewport calculations directly to the renderer's dimensions, not the full window. Here's how to adjust your code:

  1. Update dimension functions to use renderer size
    Replace your window-based dimension logic with functions that reference the renderer's canvas size:

    // Get renderer's current displayed dimensions
    function getRendererDimensions(renderer) {
      const canvas = renderer.domElement;
      const width = canvas.clientWidth;
      const height = canvas.clientHeight;
      const aspect = width / height;
      return { width, height, aspect };
    }
    
    function cameraDimensions(aspect, viewSize = 1000) {
      const caps = viewSize / 2;
      const sides = aspect * viewSize / 2;
      return { caps, sides };
    }
    
  2. Fix camera initialization and update logic
    Modify your camera setup to use the renderer's dimensions, and pass the renderer reference for resize updates:

    function getCamera(renderer) {
      const { aspect } = getRendererDimensions(renderer);
      const { caps, sides } = cameraDimensions(aspect);
      const camera = new THREE.OrthographicCamera(-sides, sides, caps, -caps, -1000, 1000);
      
      // Update camera when window resizes, using renderer's actual size
      window.addEventListener('resize', () => updateCamera(camera, renderer));
      camera.position.z = 500;
      return camera;
    }
    
    function updateCamera(camera, renderer) {
      const { aspect } = getRendererDimensions(renderer);
      const { caps, sides } = cameraDimensions(aspect);
      camera.left = -sides;
      camera.right = sides;
      camera.top = caps;
      camera.bottom = -caps;
      camera.updateProjectionMatrix();
    }
    
  3. Link renderer and camera in your engine setup
    Adjust your initEngine() function to pass the renderer reference to the camera:

    function initEngine() {
      const scene = new THREE.Scene();
      const { WebGl: renderer } = useWebGl(); // Grab the renderer instance
      const camera = getCamera(renderer); // Pass renderer to camera setup
      
      function everyFrame(callback = () => {}) {
        callback();
        renderer.render(scene, camera);
        requestAnimationFrame(() => everyFrame(callback));
      }
      return { scene, everyFrame };
    }
    
  4. Test with a fixed plane size
    When creating your plane, use a fixed geometry size (e.g., new THREE.PlaneGeometry(200, 200)). Now, no matter how you resize the window or refresh, the plane's visual size will stay consistent—because the camera's viewport perfectly matches the renderer's display area.

Why This Works

By tying the camera's aspect ratio to the renderer's canvas size instead of the full window, we ensure the camera's projection matrix aligns exactly with how the scene is displayed. This eliminates the scaling distortion you were seeing, keeping your plane's size fixed relative to the screen.

内容的提问来源于stack exchange,提问作者Samuel M. Bednarz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 15:28:11