Muito do efeito do FOV está na rapidez com que você parece se mover pelo mundo (ainda é a mesma velocidade; isso é puramente percebido). Com um FOV horizontal muito amplo, você parecerá se mover muito rápido; com estreito demais, parecerá se mover muito lentamente. 90 graus na horizontal parece ser o "ponto ideal", e o desenvolvedor do jogo pode ajustar a velocidade de movimento desejada para jogos individuais a partir daí.
Também é o caso que 4 vezes 90 graus é 360 graus, que é um círculo. A configuração do FOV horizontal para que ele mapeie bem os quadrantes dianteiro / esquerdo / traseiro / direito parece fazer sentido.
E, finalmente, há a velha castanha de precedência e inércia. Não tenho certeza se algum jogo ofereceu FOV ajustável por jogador antes do Quake, mas o Quake o fez e o padrão foi 90 graus na horizontal; é fácil imaginar outros jogos pegando 90 graus a partir daí.
Vale ressaltar que hoje em dia 90 graus está se tornando menos comum, com jogos (particularmente os modernos FPSs) configurando um valor um pouco menor - em torno de 80.
Se você deseja corrigir o aspecto do seu FOV, pode usar algo assim (não pretendo que seja o único ou o melhor caminho, mas é consistente com a calculadora do FOV em http://www.emsai.net/projects/widescreen / fovcalc / ; isso assume em relação a uma proporção básica de 4: 3 (você pode ajustar isso na chamada para CalcFovY abaixo))
float CalcFovX (float fov_y, float width, float height)
{
float a;
float y;
if (fov_y < 1) fov_y = 1;
if (fov_y > 179) fov_y = 179;
y = height / tan (fov_y / 360 * M_PI);
a = atan (width / y);
a = a * 360 / M_PI;
return a;
}
float CalcFovY (float fov_x, float width, float height)
{
float a;
float x;
if (fov_x < 1) fov_x = 1;
if (fov_x > 179) fov_x = 179;
x = width / tan (fov_x / 360 * M_PI);
a = atan (height / x);
a = a * 360 / M_PI;
return a;
}
Então chame assim:
// you should use #define of const instead of magic numbers here, which are just here for illustration purposes in this sample
fov_y = CalcFovY (playerAdjustableFOV, 4, 3); // this is your base aspect that adjusted FOV should be relative to
fov_x = CalcFovX (fov_y, width, height); // this is your actual window width and height
Os fov_x e fov_y calculados podem então ser conectados à seguinte matriz de perspectiva (convenção OpenGL):
1.0f / tan (DEG2RAD (fov_x) * 0.5f),
0,
0,
0,
0,
1.0f / tan (DEG2RAD (fov_y) * 0.5f),
0,
0,
0,
0,
(zFar + zNear) / (zNear - zFar),
-1,
0,
0,
(2.0f * zFar * zNear) / (zNear - zFar),
0
Isso fornecerá um FOV horizontal ajustado ao aspecto que mantém o FOV vertical, independentemente da resolução e proporção.