Если вы хотите самый простой код и не хотите погружаться в матрицы, попробуйте что-то вроде этого:
Vec2 screenCenter = Vec2( screensize.x/2, screensize.y/2 ); // half of your screen resolution
// try changing it to see what happens
// you can animate it to add special effects
float perspStrength = 500.0f; // actually an inverse of perspective strength
// lower values means bigger effect
Vec2 project( Vec3 pos ) // projection code
{
Vec2 localPos = pos - screenCenter; // Move point (0,0) to the center of your screen
float scale = pos.z/perspStrength; // scale your Z to ~(0-1) range
scale += 1.0f; // move your Z to ~(1-2) range
localPos.x /= scale; // scale position according to Z distance
localPos.y /= scale;
Vec2 result = localPos + screenCenter; // Move point (0,0) back to the corner
return result;
// return Vec3( result.x, result.y, scale ); // you can also return scale used for this object
// so you can render distant objects as smaller
}
Я написал этот код, предполагая, что он будет использоваться со значениями с плавающей запятой.Я выбрал 500
константу только потому, что вы предполагали, что Z находится в диапазоне (0,500), поэтому я хотел переместить его в (0-1) диапазон.Мы не хотим иметь 0
в нашем коде проекции, потому что мы будем делиться на это значение, поэтому мы добавляем 1
, чтобы переместить масштаб в диапазон (1-2).Не стесняйтесь изменить эти значения и посмотрите, что произойдет.
В соответствии с вашим вторым вопросом: Я думаю, что вы переписали этот код, используя целые числа, поэтому деление на 500 отменяет ваше значение Z=100
и онодает тот же результат, что и Z=100
вектор.Чтобы исправить это, вы можете изменить целые числа на числа с плавающей точкой, и все должно быть в порядке.Если вы не хотите или не можете этого сделать и нуждаетесь в коде для целых чисел, его нужно немного изменить:
Вместо шкалы с плавающей запятой мы можем использовать int
и представить шкалу в 1 /1000 единиц, поэтому базовая шкала будет 1000.
Самый простой способ получить шкалу:
int scale = 1000 - pos.z;
Если вам нужно масштабирование эффекта перспективы, вы можете использовать его вместо:
int perspStrength = 100;
int scale = 1000 - (pos.z*perspStrength/100);
Теперь, когда у вас есть scale
в 1/1000
единицах, вы можете масштабировать свои векторы:
localPos.x = localPos.x * scale / 1000;
localPos.y = localPos.y * scale / 1000;