Existe um algoritmo conhecido 'mais eficiente' para a detecção de colisões AABB vs Ray?
Recentemente, deparei com o algoritmo de colisão AABB vs Sphere do Arvo, e estou me perguntando se existe um algoritmo igualmente digno de nota para isso.
É preciso ter condição para esse algoritmo: eu preciso ter a opção de consultar o resultado para a distância da origem do raio até o ponto de colisão. Dito isto, se houver outro algoritmo mais rápido que não retorne distância, além de postar um que o faça, postar esse algoritmo também seria muito útil.
Indique também qual é o argumento de retorno da função e como você o usa para retornar a distância ou um caso de 'sem colisão'. Por exemplo, ele possui um parâmetro out para a distância e também um valor de retorno bool? ou simplesmente retorna um float com a distância, vs um valor de -1 para nenhuma colisão?
(Para quem não sabe: AABB = Caixa delimitadora alinhada ao eixo)
fonte
Respostas:
Andrew Woo, que, juntamente com John Amanatides, desenvolveu o algoritmo raymarching (DDA) usado onipresente em rastreadores de raios, escreveu "Fast Ray-Box Intersection" (fonte alternativa aqui ), que foi publicado em Graphics Gems, 1990, pp. 395-396. Em vez de ser construído especificamente para a integração por meio de uma grade (por exemplo, um volume voxel) como é o DDA (consulte a resposta de zacharmarz), esse algoritmo é adequado especificamente para mundos que não são subdivididos de maneira uniforme, como o mundo típico dos poliedros encontrado na maioria dos 3D jogos
A abordagem fornece suporte para 3D e, opcionalmente, faz a seleção da face posterior. O algoritmo é derivado dos mesmos princípios de integração usados nos DDAs, por isso é muito rápido. Mais detalhes podem ser encontrados no volume original Graphics Gems (1990).
Muitas outras abordagens especificamente para o Ray-AABB podem ser encontradas em realtimerendering.com .
EDIT: Uma abordagem alternativa, sem ramificação - que seria desejável na GPU e na CPU - pode ser encontrada aqui .
fonte
O que eu tenho usado anteriormente no meu raytracer:
Se isso retorna verdadeiro, ele está se cruzando, se ele retorna falso, não está se cruzando.
Se você usar o mesmo raio várias vezes, poderá pré-calcular
dirfrac
(apenas divisão no teste de interseção inteiro). E então é muito rápido. E você também tem comprimento de raio até a interseção (armazenada emt
).fonte
Ninguém descreveu o algoritmo aqui, mas o algoritmo Graphics Gems é simplesmente:
Usando o vetor de direção do raio, determine quais dos três aviões candidatos seriam atingidos primeiro . Se o seu vetor de direção do raio (não normalizado) for (-1, 1, -1), os três planos que podem ser atingidos são + x, -y e + z.
Dos 3 planos candidatos, encontre o valor t para a interseção de cada um. Aceite o plano que obtiver o maior valor de t como sendo o avião atingido e verifique se o hit está dentro da caixa . O diagrama no texto deixa isso claro:
Minha implementação:
fonte
Esta é a minha interseção de raio 3D / AABox que estou usando:
fonte
tnear
etfar
?Aqui está uma versão otimizada do que eu uso acima para GPU:
fonte
Uma coisa que você pode querer investigar é rasterizar a frente e o verso da sua caixa delimitadora em dois buffers separados. Renderize os valores x, y, z como rgb (isso funciona melhor para uma caixa delimitadora com um canto em (0,0,0) e o oposto em (1,1,1).
Obviamente, isso tem uso limitado, mas achei ótimo para renderizar volumes simples.
Para mais detalhes e código:
http://www.daimi.au.dk/~trier/?page_id=98
fonte
Aqui está o código Line vs AABB que eu tenho usado:
fonte
Isso parece semelhante ao código postado por zacharmarz.
Eu obtive esse código do livro 'Real-Time Collision Detection', de Christer Ericson, na seção '5.3.3 Interseção de raio ou segmento contra caixa'
fonte
Estou surpreso ao ver que ninguém mencionou o método de laje sem galhos de Tavian
Explicação completa: https://tavianator.com/fast-branchless-raybounding-box-intersections/
fonte
Adicionei à resposta @zacharmarz para lidar com quando a origem do raio está dentro da AABB. Nesse caso, tmin será negativo e atrás do raio, então tmax é a primeira interseção entre o raio e o AABB.
fonte