Объект в два раза ближе выглядит в два раза больше?

16

Поэтому я думал о создании 2D-игры, в которой вы также можете перемещаться вдоль оси Z, изменяя, в каком слое вы находитесь. В зависимости от глубины я хочу масштабировать свои 2D спрайты.

Однажды кто-то показал мне демо, в котором у него было много 2D-спрайтов, и с помощью прокрутки он мог изменить глубину камеры. Таким образом, при увеличении объекты будут приближаться к игроку и казаться больше. Тогда я подумал, насколько большим должен быть объект, когда он приближается на 1 единицу. Как бы вы рассчитали это? Так парень сказал мне: есть одно основное правило, которое я использую: «объекты в два раза ближе, появляются в два раза больше».

Теперь, проверяя его сам, я знаю, что правило не применяется в реальном мире;) Но есть ли некоторая константа, которая используется в вычислениях реального мира для перспективы или что-то? Или формула?

Я знаю, что это не лучшее место, чтобы задавать такой вопрос, но так как это единственный сайт, который я использую для вопросов, связанных с игрой, а мой контекст - игра, я решил попробовать. Также я ожидаю, что здесь есть человек, который знает все о трехмерных перспективах и матрицах или о чем-то еще, поскольку это может относиться к 3D-играм;)

ТЛ; др:

«объект, который в два раза ближе, кажется в два раза большим». Это не так в реальном мире. Но какая константа или формула верна?

Ягода
источник
3
Я понятия не имею, что ответ, но я знаю, как я мог узнать. Сделайте несколько снимков чего-нибудь. Может быть, лист бумаги. Возьмите их с разных известных расстояний, а затем выполните некоторые математические расчеты, чтобы рассчитать, сколько изображения занято листом бумаги, и определить соотношение по нему. Может быть веселый эксперимент!
SpartanDonut
Мне интересно, почему никто ничего не упомянул о натуральных логарифмах ...
Чад Харрисон
4
Почему это не правда? Я думаю, что это правда.
Иван Кукир
@hydroparadise Какое отношение к этому вопросу имеют натуральные логарифмы?
Натан Рид
Я просто педантичен здесь, я знаю, но «Дважды ближе» - странная фраза. Разве это не должно быть "Половина как далеко"? «Дважды» больше, но если что-то приближается, тогда расстояние уменьшается.
MrVimes

Ответы:

19

Обычно это так, в зависимости от вашей точки обзора и направления движения, а также от угла обзора.

Пример перспектив для объектов

Обратите внимание, что на первом виде с камеры, поскольку красный блок перпендикулярен к виду с камеры, объект кажется в два раза больше в идеальном соотношении 1: 2 (обратите внимание на стрелку, указывающую, что он перемещается по краю вида после перемещения в два раза ближе)

Второй блок такого же размера повернут на 45 градусов. Когда он повернут, нижний край больше не находится на том же расстоянии от камеры, что и верхний край, поэтому он не SEEM правильно масштабируется до соотношения 1: 2, но на самом деле он в два раза больше (чем в такой же угол на дальнем синем блоке, как и в ближнем синем блоке.)

В заключение это фактически означает, что ваш друг был прав, и соотношение 1: 1 («объекты в два раза ближе, они выглядят в два раза больше») является хорошим выбором.

Том Блю Пиддок
источник
Отличный ответ! Фотографии определенно делают это более ясным. На самом деле, я чувствую себя по-настоящему глупо, поскольку попробовал это до того, как опубликовать вопрос, держа мою руку перед лицом и подвигая ее ближе. И тогда я подумал: нет, это не кажется вдвое большим ... Я должен был измерить это более точно;) Перспектива - забавная вещь! Кроме того, я чувствую, что должен был сам придумать фотографии;) Но отличный ответ! Благодарность!
Берри
@ Мейсон Уилер - Сортировка: P
Tom 'Blue' Piddock
8

Объект, находящийся в два раза ближе, кажется в два раза большим. Это является следствием Фалеса, и это верно в реальном мире.

Можно утверждать, что теорема Фалеса является основным математическим инструментом, лежащим в основе перспективного проецирования, и то, что в графическом конвейере (OpenGL или DirectX) известно как деление перспективы . Это теорема, которую вы должны обязательно знать и научиться распознавать, когда ее можно использовать.

Сэм Хоцевар
источник
Отличные ссылки! Я обязательно проверю теорему Фалеса и постараюсь лучше понять графический конвейер.
Берри
7

На самом деле это в значительной степени верно (если вы перемещаете объект вдвое дальше, он выглядит вдвое большим), но это затеняет то, как визуальный размер объектов должен изменяться при движении зрителей. В частности, объекты, кажется, становятся больше быстрее, чем ближе они. Это потому, что зритель преодолевает половину расстояния намного быстрее, когда объект находится близко, по сравнению с тем, когда объект находится дальше. Или, другими словами, когда скорость зрителя постоянна, значение «половины расстояния» изменяется с изменением расстояния до объекта.

jhocking
источник
2

Поскольку вы на самом деле не работаете в трехмерном пространстве, мы можем предположить, что спрайты никогда не вращаются (вращение может быть смоделировано с перекосом и т. Д.). Это простое ограничение позволяет довольно легко получить несколько точные числа относительно того, каким должен быть размер в зависимости от расстояния. с камеры.

Во-первых, вам нужно понять, как визуализируются трехмерные объекты. Даже если камера сходится к одной точке, существует невидимая плоскость, которая выступает в качестве экрана для рисования объектов. Единственное, что вам нужно знать об экране, это то, как далеко он находится от камеры.

Вот схема того, как объект отображается на камере на двух разных расстояниях.

Как и следовало ожидать, высота объекта зависит от расстояния от камеры. НО, поскольку рендеринг происходит в ближней плоскости выбраковки, мы должны вычислить высоту спрайта в этой точке.

Некоторые основные триггерные вычисления приведут вас к следующей формуле:

f(d, v) = v/(v+d)
* Where f is the size ratio to the original sprite aka size factor
    and v is the distance to the near clipping plane (trial and error value)
    and d is the distance from the near clipping plane to the object

ПРИМЕР:

Assuming you have a sprite that is 2.5x1.8 units in size and 10 units away 
   from the camera, and that the near clipping plane is 5 units from the camera.

sizeFactor = 5/(5+10) = 0.3

renderHeight = actualHeight * sizeFactor = 1.8 * 0.3 = 0.54
renderWidth  = actualWidth * sizeFactor = 2.5 * 0.3 = 0.75

Я бы посоветовал начать с того, v=5а потом отрегулировать в зависимости от того, как это выглядит. Я могу бросить скрипку вместе, что позволит вам увидеть изменения в режиме реального времени.

TL; DR

The change in height or width should be multiplied by the following factor:

sizeFactor = v/(v+d)

Where v = Some number greater than 0 that never changes (try 1 thru 5)
  and d = the distance from the camera

So an object that is 2.5 units tall would be rendered at 2.5*sizeFactor units tall.

РЕДАКТИРОВАТЬ: Когда вы говорите двигаться вдоль оси Z, я предполагаю, что вам понадобится перспективный вид (как большинство 3D-игр; шутеры и т. Д.). Математика для расчета размера объекта на основе расстояния также будет зависеть от местоположения в кадре, похож на периферическое зрение. Вместо этого я бы попробовал это с моей математикой, которая представляет собой орфографический взгляд (например, Марио, Angry Birds, Super Smash Bros и т. Д.). Я не знаю, как вы выглядите и чувствуете, но пока это кажется реальным, игроки никогда не узнают!

DEMO!

Джим Бак
источник
Да, на самом деле я стремлюсь к ортографическому взгляду. Игра, из которой я «заимствую» мое текущее вдохновение, это Rayman Origins. В некоторых разделах игры вы можете прыгать на цветы, а затем вы подпрыгнете в другой слой с другой глубиной. Затем камера увеличивает или уменьшает изображение на эту глубину. Axamples можно увидеть в этом видео , в 4:50 и 5:00.
Берри
Кроме того, отличный ответ! Но поскольку простого подтверждения того, что правило «вдвое ближе, вдвое больше» применимо, было бы достаточно, я выбрал ответ Блю как лучший.
Берри
Спасибо и удачи в вашей игре! Но я хочу прояснить для других, что «вдвое ближе, вдвое больше» будет отлично работать, если все будет очень близко к камере. По мере того, как дела идут дальше, видимое изменение в размере уменьшается. Например, посмотрите на свой большой палец вверх, затем вытяните руку и посмотрите на нее. Размер вашего большого пальца кажется значительно меньше. После этого посмотрите на что-то далеко. Сделайте один шаг назад (примерно столько же, сколько длина руки). Заметьте, как размер почти не изменился? Если игра имеет длинное поле зрения, использование математики будет иметь большое значение.
Джим Бак
РЕДАКТИРОВАТЬ: я сделал ошибку в моем предыдущем комментарии. «В два раза ближе, в два раза больше» - это правильно, когда предметы остаются достаточно близко друг к другу относительно расстояния до камеры.
Джим Бак
Вот быстрое демо, которое я собрал, используя мышь для перемещения и колесо прокрутки, чтобы изменить глубину.
Джим Бак
0

Это не охватывалось, и я подумал, что это может быть полезно: стоит отметить, что когда вы уменьшите половину расстояния, удвоение размера в обоих измерениях X и Y увеличит в четыре раза общую площадь спрайта. Это потому что:

Area = X * Y

После увеличения:

NewArea = (x*2) * (y*2)

Это может создать впечатление, что эффект увеличения происходит быстро или слишком интенсивно. Вы можете отрегулировать коэффициент, изменив 2 в приведенной выше формуле на значение с плавающей запятой, например 1,5 или 1,33.

В качестве альтернативы я сохранил глубину (расстояние) камеры до ваших плиток в байтовом значении вместе с трансляцией камеры (X и Y), а затем рассчитал размер проецируемой плитки таким образом:

XTileSize = (255 / CameraZ) * DefaultTileWidth
YTileSize = (255 / CameraZ) * DefaultTileHeight

Обратите внимание, что CameraZэто должно быть строго между 1-255, и это ограничение может быть выгодой или проклятием для вас в будущем.

Марк Х.
источник