Shader de relatividad especial en GLSL

11

Estoy tratando de implementar un sombreador GLSL que ayuda a entender la relatividad especial de la transformación de Lorentz.

Tomemos dos observadores inerciales alineados con ejes Oy O'. El observador O'está en movimiento wrt observador Ocon velocidad v=(v_x,0,0).

Cuando se describe en términos de O'coordenadas, un evento P' = (x',y',z',ct')ha transformado las coordenadas.(x,y,z,ct)= L (x',y',z',ct')

donde L es una matriz 4x4 llamada transformación de Lorentz que nos ayuda a escribir las coordenadas del evento P 'en Ocoordenadas.

(para más detalles, consulte http://en.wikipedia.org/wiki/Lorentz_transformation#Boost_in_the_x-direction )

He escrito un primer sombreador de vértices preliminar que aplica la transformación de Lorentz dada la velocidad a cada vértice, pero no puedo hacer que la transformación funcione correctamente.

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) );

Este sombreador debe aplicarse a cada vértice y realizar la transformación no lineal de Lorentz, pero la transformación que realiza es claramente diferente de lo que esperaría (en este caso, una contracción de longitud en el eje x).

¿Alguien ya ha trabajado en el sombreador de relatividad especial para videojuegos 3D?

linello
fuente
En realidad es una transformación lineal, no no lineal, como dice la wiki que vinculaste. Entonces, lo que ves suena bien, sin embargo, es difícil decirlo sin verlo.
Maik Semder
Puede probar este sombreador en ShaderMaker para ver los efectos, pero lo que me gustaría lograr es este efecto: spacetimetravel.org/relaflug/relaflug.html Aquí deberíamos ver la contracción de la longitud en el eje x pero veo una escala incorrecta
linello
¿De verdad mueves la cámara? El enlace spacetimetravle viene con el código fuente, vale la pena echarle un vistazo allí
Maik Semder
también la velocidad 0.5 c / s es un poco pequeña, intente usar algo más grande que 0.9, el ejemplo usa 0.93 c / sy mueva la cámara con esa velocidad
Maik Semder
No, supongo que el observador Oestá en (0,0,0) mirando hacia abajo el eje z mientras el observador O'está en movimiento Ocon velocidad v_xy los objetos descritos O'están en reposo. Sé que en este sombreador de vértices, la transformación se aplica solo a los vértices, por lo que se pierde la deformación de las líneas, pero solo quiero entender y hacer que esto funcione al principio. Parece que el juego Polynomial ya hizo transformaciones de este tipo, pero el sombreador que he encontrado no tiene nada de interesante, ¡porque obtengo los mismos resultados! bit.ly/MueQqo
linello

Respuestas:

4

Para implementar la contracción de Lorentz, su mejor opción es probablemente escalar explícitamente el objeto en 1 / gamma a lo largo de la dirección del movimiento.

El problema es que la transformación de Lorentz desplaza los vértices en la dirección del tiempo, así como en el espacio, por lo que por sí solo no le dará la apariencia de un objeto en movimiento en un momento específico del tiempo. Para hacer eso, primero tendría que transformar todo el objeto y luego tomar un "corte" paralelo a los ejes espaciales, como en este diagrama:

Diagrama espacio-tiempo de contracción de Lorentz

Para calcular esto de verdad, efectivamente tendría que trazar un trazado de rayos en 4D, intersectando la línea mundial del vértice con el hiperplano 3D del momento actual en el marco de referencia del observador. Creo que el resultado de hacer esto es lo mismo que simplemente escalar en 1 / gamma.

(Para obtener un crédito adicional, tenga en cuenta el hecho de que un observador en realidad no vería todo el objeto en un solo momento: lo verían usando rayos de luz. Por lo tanto, necesitaría cruzar la línea mundial del vértice con el cono de luz pasado del observador. Esto en realidad cambia los resultados significativamente: un objeto que se aleja de usted se verá acortado, pero un objeto que se mueva hacia usted aparecerá alargado y un objeto que se mueve hacia los lados girará - vea rotación de Penrose-Terrell para más.)

Nathan Reed
fuente
Ok, pero ¿qué pasa si estoy cambiando el tiempo dentro de la simulación? Trato el tiempo como un flotador uniforme para pasar desde fuera del sombreador, ¿esto debería deformar el objeto a tiempo correctamente?
linello
Si el tiempo es una constante para cada fotograma, entonces está tomando una porción de tiempo 3D del mundo 4D, así que sí, lo que dije anteriormente es válido.
Nathan Reed
No entiendo también si tengo que implementar la aberración relativista por separado de la transformación de Lorentz.
linello
@linello Si te importa la aberración, parece que necesitas la versión más sofisticada de esto que describí en el último párrafo, es decir, intersecta la línea mundial del vértice con el cono de luz pasado del observador y mueve el vértice al punto de intersección localización espacial. Eso debería ser factible en el sombreador de vértices, creo. La transformación de Lorentz estaría involucrada solo en la configuración de la línea mundial del vértice. También tenga en cuenta que si el objeto está acelerando, girando, etc., entonces la línea del mundo es curva.
Nathan Reed