O ponto flutuante sempre foi problemático em termos de precisão em grandes mundos.
Este artigo explica os bastidores e oferece a alternativa óbvia - números de pontos fixos. Alguns fatos são realmente impressionantes, como:
"Bem, 64 bits de precisão levam você à distância mais distante de Plutão do Sol (7,4 bilhões de quilômetros) com precisão subimétrica".
Bem, a precisão do sub-micrômetro é mais do que qualquer necessidade de fps (para posições e até velocidades) e permitiria que você construa mundos realmente grandes.
Minha pergunta é: por que ainda usamos ponto flutuante se o ponto fixo tem essas vantagens? A maioria das APIs de renderização e bibliotecas de física usa ponto flutuante (e sofre suas desvantagens, portanto os desenvolvedores precisam contorná-las).
Eles são muito mais lentos?
Além disso, como você acha que os motores planetários escaláveis, como outerra ou infinito, lidam com a grande escala? Eles usam ponto fixo para posições ou possuem algum algoritmo de divisão de espaço?
Respostas:
Se você me permitir uma ficha descarada, darei um exemplo de um jogo real em que estou trabalhando (link do vídeo do YouTube).
O jogo tem um mundo infinito e processualmente gerado em um mecanismo de física. Ele usa ponto flutuante de precisão única. Depois de algumas centenas de metros de espaço no jogo, problemas de precisão começam a surgir (e pioram progressivamente à medida que você começa).
Minha solução? A cada 200m ou mais, movo o mundo inteiro de volta em 200m em direção à origem (se você deseja encontrar e experimentar um dos protótipos no meu site e exibir a sobreposição de depuração [w] antiga, pode ver isso acontecer).
Por que não usar ponto fixo? Ou precisão dupla? Em vez de precisão única? Porque todo o resto está usando um ponto flutuante de precisão única!
O mecanismo de física que estou usando o usa, o XNA usa, os dados que são carregados na placa de vídeo são formatados como ponto flutuante de precisão única. Até a própria linguagem é projetada para funcionar com números de ponto flutuante - escrever e (mais importante) ler
0.5f
é muito mais fácil do que0x80000000L
.É simplesmente uma questão do que é mais fácil na prática. E o vencedor claro é estar ciente dos problemas de precisão do ponto flutuante e escrever funções bastante simples "mover o mundo de volta ao zero" (ou implementar o particionamento de espaço ou o que melhor se adequar ao seu jogo).
E, finalmente, outro exemplo - Orbiter é um jogo (simulação, na verdade) que realmente precisa se preocupar com precisão. Não apenas no espaço, mas também no tempo (aceleração do tempo mais corpos em órbita - não quero que caiam do céu agora). Ele também usa números de ponto flutuante e emprega um hack para manter a estabilidade.
fonte
Primeiro - sim, eles são significativamente mais rápidos. Mesmo que você consiga que o ponto fixo trabalhe tão rápido quanto uma FPU "normal", o ponto flutuante real tem instruções vantajosas, como fsel para interromper a ramificação, ou o SIMD para trabalhar em vários flutuadores ao mesmo tempo. As GPUs também usam ponto flutuante, pelo menos em suas interfaces voltadas para o usuário.
Em segundo lugar, 64 bits também te levam muito longe no ponto flutuante - a maioria das pessoas ainda usa 32, mas a principal vantagem é que ele é escalável. Essa escala de pontos fixos tem uma precisão fixa. Seja medindo o sol em Plutão ou do outro lado da rua, você obtém a mesma precisão. O ponto flutuante fornecerá resultados muito mais precisos quando todos os valores envolvidos forem menores. Como é esperado que as bibliotecas de física genéricas funcionem pelo menos de maneira passável com muitos jogos em escalas diferentes - e alguns jogos em si podem ter escalas muito diferentes -, eles precisam usar um tipo de número que funcione em várias escalas.
fonte
Outro ponto importante a destacar é que os carros alegóricos não são tão imprecisos quanto as pessoas aqui parecem pensar. Um flutuador de 32 bits possui 24 bits de precisão inteira. Isso significa que ele é pelo menos tão preciso quanto um valor de ponto fixo de 24 bits para um determinado intervalo. Enquanto os flutuadores se tornam menos precisos quanto maior o valor, um valor de ponto fixo simplesmente transborda e quebra em algum momento. Reduzir a precisão é uma alternativa melhor. Os carros alegóricos também podem transbordar, mas muito, muito mais tarde. Eu gostaria de ver seus rostos quando seu mundo repentinamente se aproxima de -2 ^ 31 devido ao estouro de pontos fixos.
Os valores de ponto flutuante de 64 bits têm precisão de 53 bits, portanto são realmente precisos.
fonte
Em um contexto de FPS, os valores de ponto fixo podem realmente ser um passivo. Perto de zero ponto flutuante é mais preciso. É somente em grandes distâncias que o ponto fixo se torna mais preferível. A resposta é simplesmente que depende do contexto.
Em algo como uma galáxia, você pode usar quadros de referência. Use uma escala enorme para os sistemas solares e, em seguida, use o centro do Sol (ou ponto similar) como ponto de origem para qualquer coisa dentro do sistema. Usando este sistema, você pode comer seu bolo e comê-lo, por assim dizer, e não é difícil de imaginar.
No IIRC, o desenvolvedor do Infinity afirmou que ele estava continuamente interagindo em torno de questões de escala em uma de suas entrevistas.
fonte
Se ainda não o fez, deve consultar definitivamente o tutorial Planet Rendering no GameDev.net. Quanto à divisão espacial, uma solução é manter duas variáveis de posição separadas - uma macro escala e uma micro escala. Isso funciona muito bem (testado).
A solução exata depende de como você planeja lidar com distâncias extremas no motor - você planeja portões de salto ou compressão de tempo?
fonte
Uma das razões é que a aritmética de ponto flutuante é "boa o suficiente" (ou pelo menos tem sido), produz resultados razoavelmente precisos rapidamente.
Desde que você esteja ciente das limitações da aritmética de ponto flutuante e altere seus algoritmos para lidar com eles (consulte a resposta de Andrew Russell), você produzirá um código que "funcionará".
fonte
Eu estou escrevendo um jogo No meu jogo / programa, eu desenho uma nave espacial na origem usando uma câmera bastante fixa e meu planeta eu desenho usando uma câmera separada. E essas duas coisas resolvem o problema para mim, mas meu planeta ainda não está muito detalhado. Quanto à solução que Andrew Russell mencionou sobre mudar o mundo (e suponho que a câmera e seus habitantes voltem à origem), eu realmente não tentaria isso se você planeja tornar o jogo um jogo em rede. Se você movesse o mundo no aplicativo de servidor com base nos movimentos de cada cliente, o mundo acabaria lutando por uma posição. E tomaria sua posição o tempo todo de todos os jogadores, o que seria uma enorme falha.
fonte