Three.js: Расчет FOV для перспективной камеры

Созданный на 2 февр. 2012  ·  19Комментарии  ·  Источник: mrdoob/three.js

Поскольку у меня нет предыдущего опыта работы с 3D, я сталкиваюсь с некоторыми проблемами, которые могут быть известны вам 3D-профессионалам;).
У меня есть самые разные размеры сцены (800x600, 1200x100 и т. Д.).
Какую формулу я могу использовать, чтобы убедиться, что объект с положением z, равным 0, а ширина и высота такие же, как у сцены, заполняет всю сцену.

Например: Сетка объекта A имеет размер 1200x100 и находится в позиции Z 0. Сцена также имеет размер 1200x100. Камера находится в положении по оси z 1500. Каков угол обзора, чтобы объект заполнял сцену?

Что-то вроде ((A / B) * C) - это то, что я ищу: D.

Бесконечное количество похвал тому, кто достаточно талантлив, чтобы ответить на мой вопрос :)

Question

Самый полезный комментарий

Видимый height учетом вертикального поля зрения vFOV и расстояния от камеры dist равен

height = 2 * Math.tan( ( vFOV / 2 ) ) * dist;

Видимый width равен

aspect = window_width / window_height;
hFOV = 2 * Math.atan( Math.tan( vFOV / 2 ) * aspect );
width  = 2 * Math.tan( ( hFOV / 2 ) ) * dist;

Параметр поля зрения камеры в THREE.js - вертикальный.

Используйте два набора уравнений, чтобы дважды вычислить требуемую vFOV и выбрать больший ответ.

Все 19 Комментарий

Видимый height учетом вертикального поля зрения vFOV и расстояния от камеры dist равен

height = 2 * Math.tan( ( vFOV / 2 ) ) * dist;

Видимый width равен

aspect = window_width / window_height;
hFOV = 2 * Math.atan( Math.tan( vFOV / 2 ) * aspect );
width  = 2 * Math.tan( ( hFOV / 2 ) ) * dist;

Параметр поля зрения камеры в THREE.js - вертикальный.

Используйте два набора уравнений, чтобы дважды вычислить требуемую vFOV и выбрать больший ответ.

Большое спасибо за ответ :)
Хотя я немного запутался. Откуда мне взять переменную vFOV?
Высота объекта должна заполнять сцену?
Если это так, я получаю странные числа (в диапазоне 1000), так как мне преобразовать это в возможное поле зрения.

Я создал Fiddle http://jsfiddle.net/dmYgr/6/
Вы можете показать мне там, как это сделать?

Еще раз большое вам спасибо. Из твоего поста я уже чувствую, что ты больше гений, чем я;)

Используйте первое уравнение и решите для vFOV , а затем используйте его как параметр fov для камеры.

Моя сцена 800 * 600.
Дальность камеры 1000.

Как использовать эти числа в вашей формуле.
Не знаю, что залить в vFOV.

высота = 2 * Math.tan ((vFOV / 2)) * расстояние; <- Вы говорите мне начать здесь, но какое число должно заменить vFOV?

Используйте первое уравнение и решите для vFOV вот так

vFOV = 2 * Math.atan( height / ( 2 * distance ) );

затем используйте это как параметр fov для камеры.

var renderWidth = 800;
var renderHeight = 600;
var cameraPosition = 1000;
var vFOV = 2 * Math.atan( renderWidth / ( 2 * cameraPosition ) );
var height = 2 * Math.tan( ( vFOV / 2 ) ) * cameraPosition;
var aspect = renderWidth / renderHeight;
var hFOV = 2 * Math.atan( Math.tan( vFOV / 2 ) * aspect );
var width  = 2 * Math.tan( ( hFOV / 2 ) ) * cameraPosition;

Результат:
vFOV = 0,7610127542247298, что не является допустимым FOV.

var vFOV = 2 * Math.atan( renderHeight / ( 2 * cameraPosition ) );
var height = 2 * Math.tan( ( vFOV / 2 ) ) * cameraPosition;

var aspect = renderWidth / renderHeight;
var hFOV = 2 * Math.atan( Math.tan( vFOV / 2 ) * aspect );
var width  = 2 * Math.tan( ( hFOV / 2 ) ) * cameraPosition;

vFOV = 0,5829135889557342, что также не является допустимым FOV.

Можете ли вы заполнить пример для меня и показать пример, который действительно дает действительное число FOV?
Правильное число в приведенном выше примере - около 37.

В твоей скрипке,

высота = высота сетки вашего самолета = 500.

distance = camera.z - plane.z = 1000 - 100 = 900.

vFOV = 2 * Math.atan (высота / (2 * расстояние)) = 0,5419 радиан, или 31,04 градуса.

2 * Math.atan (500 / (2 * 900)) = 0,5418937006768411 согласно моему браузеру (google chrome)

Извините, я забыл показать преобразование радианов в градусы. Я обновил свой предыдущий пост.

Спасибо огромное! : D
Ха, на это ушло примерно 10 ответов, но теперь это работает :).
Еще раз спасибо!

@Tobiasartz :-)

Западный Лэнгли. Ты король. Спасибо.

Это было очень полезно !! Спасибо, @WestLangley !

Спасибо @WestLangley !!
Поскольку мне потребовалось время, чтобы понять, что мне нужно добавить преобразование радиантов в градусы, я добавляю здесь пример с окончательным кодом:

var distance = 1000;
var FOV = 2 * Math.atan( window.innerHeight / ( 2 * distance ) ) * 180 / Math.PI;
var camera = new THREE.PerspectiveCamera( FOV, window.innerWidth/window.innerHeight, 0.1, distance );
camera.position.z = distance;

@ Emanuele-Spatola Ваша формула не имеет смысла. window.innerHeight имеет единицы пикселей. distance скорее всего, нет. Видимая высота должна иметь те же единицы, что и расстояние.

Я обновил скрипку Tobiasartz с помощью этой формулы, и, похоже, она работает:
http://jsfiddle.net/dmYgr/63/
Размер холста - 500 пикселей, размер плоскости - 495x495 пикселей, а вокруг него - около 5 пикселей границы.
Почему расстояние 1000 пикселей не является допустимым?

http://jsfiddle.net/dmYgr/65/

Почему расстояние 1000 пикселей не является допустимым?

Вы когда-нибудь помещали камеру на 1000 пикселей перед объектом?

Вы можете разместить настоящую камеру на расстоянии 10 футов, чтобы смотреть на сцену шириной 10 футов. Точно так же вы можете разместить виртуальную камеру на расстоянии 1000 пикселей, чтобы увидеть сцену шириной 1000 пикселей.

Я использую это, когда знаю высоту, ширину сцены и расстояние до камеры ...

var distance = 1000,height=window.innerHeight,width=window.innerWidth
var diag = Math.sqrt((height*height)+(width*width))
var FOV = 2 * Math.atan( diag / ( 2 * distance ) ) * 180 / Math.PI;
var camera = new THREE.PerspectiveCamera( FOV, window.innerWidth/window.innerHeight, 0.1, distance );
camera.position.z = distance;

Таким образом также обрабатываются такие ситуации, как высота> ширина ...

Была ли эта страница полезной?
0 / 5 - 0 рейтинги