Перейти к содержимому


Фотография

Вращение 3D вектора


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 3

#1 Оффлайн   TC1061

TC1061
  • Пользователи
  • Сообщений: 39
  • Уровень сигнала: 6,93%
  • В игре: 59 час. 28 мин.

Отправлено 11 Июнь 2018 - 22:12

Ну вообщем, я пытался сделать воксельный рэйкастер. Мне нужна была функция вращения 3D вектора.
Она должна принимать 5 аргументов, координаты вектора (X,Y,Z) и углы вращения (по Y, по X) и вращать вектор вокруг нулевой точки (0,0,0). Я вот попытался свою функцию реализовать, но она работает неправильно:

Спойлер

Кто нибудь может написать правильно вращающий эквивалент? Буду очень благодарен.


Сообщение отредактировал Alex: 12 Июнь 2018 - 14:32
спойлер


#2 Оффлайн   ECS

ECS
  • Гуру
  • Сообщений: 204
  • Уровень сигнала: 0,49%
  • В игре: 4 час. 10 мин.
  • ГородСанкт-Петербург

Награды

   10                  

Отправлено 12 Июнь 2018 - 00:26

Интересно, для чего тебе вращение трехмерных векторов при написании рейкастера, если соль алгоритма именно в минимизации векторных расчетов и статичной производительности? Но хозяин - барин. Во-первых, на кой дьявол постоянно использовать конверсию из градусов в радианы? Сожрет же львиную долю ресурсов ЦП, а толку ноль. Юзай сразу радианы, а в человекопонятный градусный формат выводи лишь в интерфейсе. Во-вторых, очень много локальных переменных - рендерер загнется от "out of memory" на сценах с удаленной от точки каста геометрией, т.к. GC не успеет подтереть кучки локального навоза. В-третьих, незачем столь часто обращаться к таблице math и вычислять значения синусов: достаточно разово передать их в расчетную функцию. Также разумнее использовать векторные координаты в качестве последних аргументов функций, чтобы более эффективно передавать результат расчетов из одной функции в другую, хотя лично я бы вообще ограничился тремя локальными переменными для всех векторов и работал бы только с ними. В-четвертых, в нормализации углов особого смысла нет, т.к. тригонометрические функции автоматом работают с углами любого формата. Разве что если ты захочешь сделать заранее вычисленную таблицу косинусов/синусов и получать значения углов уже из нее - вот тогда да, приводить углы к диапазону [-2π; +2π] уже разумно, хотя на практике прирост производительности толком не заметен.

Спойлер

  • Alex, NEO, eu_tomat и еще 1 это нравится

#3 Оффлайн   TC1061

TC1061
  • Автор темы
  • Пользователи
  • Сообщений: 39
  • Уровень сигнала: 6,93%
  • В игре: 59 час. 28 мин.

Отправлено 12 Июнь 2018 - 12:31

Интересно, для чего тебе вращение трехмерных векторов при написании рейкастера, если соль алгоритма именно в минимизации векторных расчетов и статичной производительности?

А как без вращения 3D точек сделать 3D рэйкастер? Я не знаю как. Вот у меня вот такие функции отвечают за рэйкастинг:

Спойлер

 

Если что, то это все работает в love2d. Вот я поставил твои функции, но все равно как то не то. На рендеринг поставлен плоский мир, и он должен выглядеть соотвествующе, но как бы не так:

Спойлер

Может, нужно использовать углы Эйлера или кватернионы?


Сообщение отредактировал Alex: 12 Июнь 2018 - 14:31
сокращение цитаты, спойлер


#4 Оффлайн   ECS

ECS
  • Гуру
  • Сообщений: 204
  • Уровень сигнала: 0,49%
  • В игре: 4 час. 10 мин.
  • ГородСанкт-Петербург

Награды

   10                  

Отправлено 12 Июнь 2018 - 22:46

А как без вращения 3D точек сделать 3D рэйкастер?

 
Берешь FOV камеры, а также ее текущий поворот, например, по горизонтали. Через цикл изменяешь угол будущего луча в диапазоне [поворот камеры - FOV / 2; поворот камеры + FOV / 2] с заранее рассчитанными шагом, равным ширина экрана / FOV (чтобы число лучей было равным ширине экрана). Далее необходимо прокастовать луч, следующий вдоль полученного угла вплоть до желаемой дистанции прорисовки. Поскольку рейкастинг всегда выполняется с определенной точностью, то разумнее всего будет разово высчитать итеративное смещение кусочка луча по оси X через sin(угол луча) * точность и по оси Y через cos. Полученные значения необходимо раз за разом прибавлять к точке старта луча, чтобы усмешно достигнуть конца. Ну, а далее проще простого: пробегаешься циклом по всей длине луча, попутно вычисляя мировые координаты вокселя по горизонтали. А затем повторяешь вышеописанное для вертикальной ориентации, проверяя наличие вокселя в обоих плоскостях и делая с ним все, что только заблагорассудится.
 
Соль подобного подхода в том, что число тригонометрических операций будет эквивалентно ширина * высота экрана: и никаких тебе векторных вращений и бессмысленных расчетов. Цветами выделил инфу из этой пикчи:
 
QgL3iAu.png?1
 

Вот я поставил твои функции, но все равно как то не то

 
Значит, ищи ошибку. Я твой софт не кодил, и дебажить его не намерен. Формулы выше я скопипастил с собственного 3D-движка для опенкомпов, который с удовольствием их кушает. К слову, несмотря на наличие динамического освещения с полной перспективной коррекции, реализован он безо всяких углов Эйлера, матриц, кватернионов и прочей чуши на чистой линейной математике уровня 9 класса
 

Может, нужно использовать углы Эйлера или кватернионы?

 
Зачем, заче-е-ем? К чему этот геморрой, когда сам алгоритм проще пареной репы? Подобное еще на Сегу во времена Вульфа кодили, слухом не слыхивая о подобной терминологии в компьютерной графике. Ты точно рейкастинг имеешь в виду, а не полноценное трехмерное проецирование со всеми вытекающими?


Сообщение отредактировал ECS: 14 Июнь 2018 - 11:00

  • Sharplook, eu_tomat и Koteyk0o это нравится




Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных