Three.js正交相机场景下canvas高度过大时原点偏移问题咨询
问题根源
偏移由三个核心设置错误共同导致:
- 正交相机视口高宽比和画布实际显示高宽比不匹配:你将相机的
top/bottom参数和自定义逻辑变量height绑定,但实际canvas被CSS限制为800px高、1568px宽,当height设为40000时,相机高宽比(40000:1568)和画布实际显示高宽比(800:1568)完全错位,自然会出现中心偏移、内容拉伸的问题。 - 渲染画布尺寸设置错误:不需要把
renderer.setSize的高度设为和逻辑变量height一致,画布尺寸只需要匹配实际DOM容器的尺寸即可,过大的画布尺寸只会造成不必要的性能损耗,还会因为CSS缩放导致显示异常。 - 远裁剪面参数设置不合理:当前相机
far参数仅为8000,当逻辑高度变大后,部分场景元素可能超出裁剪范围被剔除,也会影响显示效果。
修复方案
- 保持
renderer.setSize的参数和DOM容器实际尺寸一致,固定为1568、800 - 正交相机的
top/bottom参数按画布实际高宽比计算,不要和逻辑世界的高度变量绑定 - 调大相机
far参数,保证所有场景元素都在视锥体内
修复后代码
<html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../three.min.js"></script> <style> #webGL { width: 1568px; height: 800px; } </style> </head> <body> <div id="webGL"> </div> <script> /* Boilerplate */ var scene = new THREE.Scene(); // 逻辑世界尺寸,和渲染、相机参数解耦 var worldWidth = 1568 var worldHeight = 40000 // 画布实际渲染尺寸,和DOM容器保持一致 var canvasWidth = 1568 var canvasHeight = 800 // 相机参数按画布高宽比设置,far调大到100000覆盖世界范围 var camera = new THREE.OrthographicCamera(-canvasWidth/2,canvasWidth/2,canvasHeight/2,-canvasHeight/2,1,100000) camera.position.set(0,100,0) camera.up.set(0,0,1) camera.lookAt(new THREE.Vector3(0,0,0)) var renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(canvasWidth, canvasHeight); renderer.setClearColor("white") document.getElementById("webGL").appendChild(renderer.domElement); let testGeom = new THREE.PlaneGeometry(200,200) let material = new THREE.MeshBasicMaterial({color:'black',side: THREE.DoubleSide}) var cube = new THREE.Mesh(testGeom,material) cube.rotation.x+=Math.PI/2 cube.position.z = worldHeight/2 scene.add(cube); let origin = new THREE.PlaneGeometry(50,50) let originMaterial = new THREE.MeshBasicMaterial({color:'red',side:THREE.DoubleSide}) let originMesh = new THREE.Mesh(origin,originMaterial) originMesh.rotation.x+=Math.PI/2 scene.add(originMesh) scene.position.set(0,0,0) var helper = new THREE.GridHelper(80,5,0x000ff,0x808080) //size,step scene.add(helper) var flag = false var render = function() { requestAnimationFrame(render); renderer.render(scene, camera); }; render(); </script> </body> </html>
如果需要调整视野显示的范围,只需要修改正交相机的left/right/top/bottom的缩放系数即可,不需要修改渲染画布尺寸。
内容的提问来源于stack exchange,提问作者coderglh
相关产品推荐
相关产品推荐

