Shader de relatividade especial em GLSL

11

Estou tentando implementar um shader GLSL que ajuda a entender a relatividade especial Lorentz Transformation.

Vamos pegar dois observadores inerciais alinhados ao eixo Oe O'. O observador O'está em movimento, observador Ocom velocidade v=(v_x,0,0).

Quando descrito em termos de O'coordenadas, um evento P' = (x',y',z',ct')transformou coordenadas(x,y,z,ct)= L (x',y',z',ct')

onde L é uma matriz 4x4 chamada transformação de Lorentz, que nos ajuda a escrever as coordenadas do evento P 'em Ocoordenadas.

(para obter detalhes, consulte http://en.wikipedia.org/wiki/Lorentz_transformation#Boost_in_the_x-direction )

Eu escrevi um primeiro shader de vértice preliminar que aplica a transformação de Lorentz, dada a velocidade de cada vértice, mas não consigo fazer com que a transformação funcione corretamente.

vec3 beta= vec3(0.5,0.0,0.0);
float b2 = (beta.x*beta.x + beta.y*beta.y + beta.z*beta.z )+1E-12; 
float g=1.0/(sqrt(abs(1.0-b2))+1E-12); // Lorentz factor (boost)
float q=(g-1.0)/b2;

//http://en.wikipedia.org/wiki/Lorentz_transformation#Matrix_forms
vec3 tmpVertex = (gl_ModelViewMatrix*gl_Vertex).xyz;
float w = gl_Vertex.w;

mat4  lorentzTransformation =
        mat4(
            1.0+beta.x*beta.x*q ,   beta.x*beta.y*q ,   beta.x*beta.z*q , beta.x*g ,
            beta.y*beta.x*q , 1.0+beta.y*beta.y*q ,   beta.y*beta.z*q , beta.y*g ,
            beta.z*beta.x*q ,   beta.z*beta.y*q , 1.0+beta.z*beta.z*q , beta.z*g ,
            beta.x*g , beta.y*g , beta.z*g , g
            );
vec4 vertex2 = (lorentzTransformation)*vec4(tmpVertex,1.0);


gl_Position = gl_ProjectionMatrix*(vec4(vertex2.xyz,1.0) );

Esse sombreador deve ser aplicado a todos os vértices e executar a transformação não linear de Lorentz, mas a transformação que ele realiza é claramente diferente do que eu esperaria (neste caso, uma contração de comprimento no eixo x).

Alguém já trabalhou no shader de relatividade especial para videogame 3D?

linello
fonte
Na verdade, é uma transformação linear, não linear, como o wiki que você vinculou. Portanto, o que você vê soa bem, no entanto, difícil de dizer com certeza sem vê-lo.
Maik Semder
Você pode experimentar esse shader no ShaderMaker para ver os efeitos, mas o que eu gostaria de obter é esse efeito: spacetimetravel.org/relaflug/relaflug.html Aqui devemos ver a contração do comprimento no eixo x, mas vejo uma escala incorreta
Linux
Você realmente move a câmera? O spacetimetravle-link vem com código fonte, que vale poder ter um olhar lá
Maik Semder
Também a velocidade de 0,5 c / s é um pouco pequeno, tentar usar algo maior do que 0,9, o exemplo usa 0,93 C / S e mover a câmara com que velocidade
Maik Semder
Não, suponho que o observador Oesteja (0,0,0) olhando para o eixo z enquanto o observador O'estiver em movimento, Ocom velocidade, v_xe os objetos descritos O'estão em repouso. Eu sei que neste shader de vértice a transformação é aplicada apenas para vértices, para que a deformação de linhas seja perdida, mas eu só quero entender e fazer isso funcionar primeiro. Parece que o jogo Polynomial já fez transformações desse tipo, mas o shader que encontrei não é nada interessante, porque eu recebo os mesmos resultados! bit.ly/MueQqo
linello

Respostas:

4

Para implementar a contração de Lorentz, sua melhor aposta é provavelmente apenas escalar explicitamente o objeto em 1 / gama na direção do movimento.

O problema é que a transformação de Lorentz desloca os vértices na direção do tempo e também no espaço, portanto, por si só, não lhe dará a aparência de um objeto em movimento em um momento específico no tempo. Para fazer isso, você deve primeiro transformar o objeto inteiro e, em seguida, fazer uma "fatia" paralela aos eixos espaciais, como neste diagrama:

Diagrama espaço-temporal da contração de Lorentz

Para calcular isso de verdade, você precisaria efetivamente traçar o raio em 4D, cruzando a linha do mundo do vértice com o hiperplano 3D do momento atual no quadro de referência do observador. Eu acredito que o resultado de fazer isso é o mesmo que simplesmente escalar 1 / gama.

(Para obter crédito extra, leve em consideração o fato de que um observador não veria o objeto inteiro em um único momento: eles o veriam usando raios de luz. Portanto, é necessário cruzar a linha do mundo vértice com o cone de luz do passado do observador.Isso realmente altera significativamente os resultados: um objeto se afastando de você parecerá encurtado, mas um objeto se movendo em sua direção parecerá alongado e um objeto que se moverá lateralmente será girado - consulte Rotação Penrose-Terrell para mais.)

Nathan Reed
fonte
Ok, mas e se eu estiver mudando o tempo dentro da simulação? Trato o tempo como um flutuador uniforme a ser passado de fora do shader; isso deve deformar o objeto no tempo corretamente?
Linello
Se o tempo é uma constante para cada quadro, você está usando uma fatia de tempo 3D do mundo 4D, então sim, o que eu disse acima vale.
Nathan Reed
Também não entendo se tenho que implementar a aberração relativista separadamente da transformação de Lorentz.
Linello
@linello Se você se preocupa com a aberração, parece que precisa da versão mais sofisticada disso que descrevi no último parágrafo - isto é, cruza a linha do mundo do vértice com o cone de luz passado do observador e move o vértice para o ponto de interseção. localização espacial. Isso deve ser possível no shader de vértices, eu acho. A transformação de Lorentz estaria envolvida apenas na criação da linha mundial do vértice. Observe também que, se o objeto estiver acelerando, girando etc., a linha do mundo será curvada.
Nathan Reed