如何让Three.js平面几何体尺寸不随渲染器/屏幕尺寸变化
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:
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 }; }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(); }Link renderer and camera in your engine setup
Adjust yourinitEngine()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 }; }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

