Threejs — поворот камеры на 90 градусов, а не объектов

#javascript #three.js #webgl

#javascript #three.js #webgl

Вопрос:

В моем проекте в сцене много объектов, поэтому я бы предпочел вращать камеру, а не объекты. Как я могу это сделать? Я использую OrthographicCamera, что означает, что я работаю над 2D.

Текущее положение камеры (пример слева)

 const camera =  new OrthographicCamera(0, width, 0, height, 0, 20);
camera.position.set(x, y, 1);
camera.clearViewOffset();
camera.updateProjectionMatrix();
 

Справа — это то, чего я хотел бы достичь…

введите описание изображения здесь

Когда я использую camera.rotation.z = Math.PI * 0.5; объекты, они исчезают за видовым экраном, потому что моя камера установлена в верхнем левом углу. К сожалению, настройки камеры зависят от координат, которые она получает из BE.

Ответ №1:

Попробуйте с:

camera.rotation.z = математика.PI * 0.5;

 const aspect = window.innerWidth / window.innerHeight;
const frustumSize = 2;

const camera = new THREE.OrthographicCamera(0.5 * frustumSize * aspect / -2, 0.5 * frustumSize * aspect / 2, frustumSize / 2, frustumSize / -2, 0.01, 10);
camera.position.z = 1;
camera.rotation.z = Math.PI * 0.5;

const scene = new THREE.Scene();

scene.add(new THREE.AxesHelper());

const renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

renderer.render(scene, camera); 
 body {
      margin: 0;
} 
 <script src="https://cdn.jsdelivr.net/npm/three@0.124/build/three.js"></script> 

Комментарии:

1. Ваша идея поворачивает камеру, но объекты исчезают (они где-то высоко). И это происходит потому, что координаты для этих объектов определяются на основе верхнего левого угла (я не могу его изменить) :/ new OrthographicCamera(left: 0, right: width, top: 0, bottom: height, near: 0, far: 20);

2. есть еще идеи? 🙂

Ответ №2:

Поскольку ваше усечение имеет 0,0 в левом верхнем углу, вам нужно добавить несколько других родительских элементов, чтобы переместить точку поворота камеры.

 const {
  Object3D,
  OrthographicCamera,
  Scene,
  Renderer,
  GridHelper,
  WebGLRenderer,
  MathUtils,
} = THREE;
const {
  lerp,
} = MathUtils;

const canvas = document.querySelector('canvas')
const {width, height} = canvas.getBoundingClientRect();
const scene = new Scene();

const camera = new OrthographicCamera(0, width, 0, height, 0, 20);
// cameras look down -Z so this camera is looking from 20 to 0
camera.position.z = 20;

const cameraBase = new Object3D();
const cameraPivot = new Object3D();
cameraBase.add(cameraPivot);
cameraBase.position.set(width / 2, height / 2, 0);
cameraPivot.add(camera);
cameraPivot.position.set(-width / 2, -height / 2, 0);
scene.add(cameraBase);


addRect('red',    -10, -10, 5,  20,  20);
addRect('cyan',    20,  20, 5,  20,  20);
addRect('green',  100,  50, 5,  25,  30);
addRect('yellow', 130,  70, 6, 100,  50);
addRect('orange', 170,  90, 7,  50,  75);
addRect('white',    1,   1, 5, 298, 148);

function addRect(color, x, y, z, width, height) {
  // make a 1x1 unit grid
  const grid = new GridHelper(1, 1, color, color);
  // move it so it starts at 0,0 and goes to 1,1
  grid.geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(0.5, 0, 0.5));
  // grids are in x,z plane. rotate to x,y plane
  grid.rotation.x = Math.PI * -0.5;
  // position it
  grid.position.set(x, y, z);
  // make it the size we want in pixel units
  grid.scale.set(width, 1, height);
  scene.add(grid);
}

const renderer = new WebGLRenderer({canvas});


function render(now) {
  cameraBase.rotation.z = (now * 0.001);
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}
requestAnimationFrame(render); 
 body { background: #444; } 
 <script src="https://cdn.jsdelivr.net/npm/three@0.124/build/three.js"></script>
<canvas></canvas> 

Комментарии:

1. Круто! мы близки! не могли бы вы немного упростить свой код? избавьтесь от анимации, потому что моя версия статична (и я поворачиваю камеру после нажатия на кнопку), и я действительно не понимаю, почему вы создаете object3d

2. Возможно, вам следует прочитать несколько руководств . Object3D S позволяет нам переместить камеру в центр, повернуть ее, затем переместить обратно в верхний левый угол, чтобы она работала для данной матрицы проекции. Кроме того, нет, я не буду менять код. Для вас должно быть тривиально удалить анимацию и установить cameraBase.rotation.z значение some Math.PI * 0.5 или Math.PI or Math.PI * 1.5 на основе любых входных данных, которые вы хотите.

3. Теперь у меня другая проблема .. все работает нормально, но когда я передаю фотографию с помощью threejs (в качестве слоя), threejs не следует за фотографией: /