Shader de relativité restreinte en GLSL

11

J'essaie d'implémenter un shader GLSL qui aide à comprendre la relativité restreinte Lorentz Transformation.

Prenons deux observateurs inertiels alignés sur l'axe Oet O'. L'observateur O'est en mouvement par rapport Oà la vitesse v=(v_x,0,0).

Lorsqu'il est décrit en termes de O'coordonnées, un événement P' = (x',y',z',ct')a transformé les coordonnées(x,y,z,ct)= L (x',y',z',ct')

où L est une matrice 4x4 appelée transformation de Lorentz qui nous aide à écrire les coordonnées de l'événement P 'en Ocoordonnées.

(pour plus de détails, consultez http://en.wikipedia.org/wiki/Lorentz_transformation#Boost_in_the_x-direction )

J'ai écrit un premier vertex shader préliminaire qui applique la transformation de Lorentz étant donné la vitesse à chaque sommet, mais je n'arrive pas à faire fonctionner la transformation correctement.

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

Ce shader devrait s'appliquer à chaque sommet et effectuer la transformation de Lorentz non linéaire, mais la transformation qu'il effectue est clairement différente de ce que j'attendais (dans ce cas, une contraction de longueur sur l'axe des x).

Quelqu'un a-t-il déjà travaillé sur un shader de relativité spécial pour un jeu vidéo 3D?

linello
la source
C'est en fait une transformation linéaire, non non linéaire, comme le dit le wiki que vous avez lié. Donc, ce que vous voyez semble correct, cependant, difficile à dire avec certitude sans le voir.
Maik Semder
Vous pouvez essayer ce shader dans ShaderMaker pour voir les effets, mais ce que je voudrais obtenir, c'est cet effet: spacetimetravel.org/relaflug/relaflug.html Ici, nous devrions voir la contraction de la longueur sur l'axe des x mais je vois une mise à l'échelle incorrecte
linello
Déplacez-vous réellement la caméra? Le lien spacetimetravle est livré avec le code source, cela pourrait valoir le coup d'oeil
Maik Semder
aussi la vitesse 0,5 c / s est un peu petite, essayez d'utiliser quelque chose de plus grand que 0,9, l'exemple utilise 0,93 c / s et déplacez l'appareil photo avec cette vitesse
Maik Semder
Non, je suppose que l'observateur Oest en (0,0,0) regardant vers le bas sur l'axe z tandis que l'observateur O'est en mouvement par rapport Oà la vitesse v_xet que les objets décrits O'sont au repos. Je sais que dans ce vertex shader, la transformation n'est appliquée qu'aux sommets, donc la déformation des lignes est perdue, mais je veux juste comprendre et faire fonctionner cela au début. On dirait que le jeu Polynomial a déjà fait des transformations de ce genre, mais le shader que j'ai trouvé n'a rien d'intéressant, car j'obtiens les mêmes résultats! bit.ly/MueQqo
linello

Réponses:

4

Pour implémenter la contraction de Lorentz, votre meilleur pari est probablement de mettre à l'échelle explicitement l'objet de 1 / gamma le long de la direction du mouvement.

Le problème est que la transformation de Lorentz déplace les sommets dans la direction du temps ainsi que dans l'espace, donc elle ne vous donnera pas à elle seule à quoi ressemble un objet en mouvement à un moment précis dans le temps. Pour ce faire, vous devez d'abord transformer l'objet entier, puis en faire une "tranche" parallèle aux axes spatiaux, comme dans ce diagramme:

Diagramme espace-temps de contraction de Lorentz

Pour calculer cela pour de vrai, vous devez effectivement lancer un lancer de rayons dans 4D, en coupant la ligne du monde du sommet avec l'hyperplan 3D du moment actuel dans le cadre de référence de l'observateur. Je crois que le résultat de cette opération est identique à une simple mise à l'échelle de 1 / gamma.

(Pour un crédit supplémentaire, prenez en compte le fait qu'un observateur ne verrait pas réellement l'objet entier à un seul instant: il le verrait en utilisant des rayons lumineux. Il vous faudrait donc croiser la ligne mondiale du sommet avec le cône de lumière passé de l'observateur. Cela change en fait les résultats de manière significative: un objet s'éloignant de vous semblera raccourci, mais un objet se déplaçant vers vous apparaîtra allongé et un objet se déplaçant latéralement sera tourné - voir Rotation Penrose-Terrell pour plus.)

Nathan Reed
la source
D'accord, mais si je change l'heure de la simulation? Je traite le temps comme un flotteur uniforme à passer de l'extérieur du shader, cela devrait-il déformer correctement l'objet dans le temps?
linello
Si le temps est une constante pour chaque image, alors vous prenez une tranche de temps 3D du monde 4D, alors oui, ce que j'ai dit ci-dessus est valable.
Nathan Reed
Je ne comprends pas aussi si je dois implémenter l'aberration relativiste séparément de la transformation de Lorentz.
linello
@linello Si vous vous souciez de l'aberration, il semble que vous ayez besoin de la version la plus sophistiquée que j'ai décrite dans le dernier paragraphe - c'est-à-dire, coupez la ligne du monde du sommet avec le cône de lumière passé de l'observateur et déplacez le sommet jusqu'au point d'intersection. localisation spatiale. Cela devrait être faisable dans le vertex shader, je pense. La transformée de Lorentz ne serait impliquée que dans l'établissement de la ligne mondiale du sommet. Notez également que si l'objet accélère, tourne, etc., la ligne du monde est incurvée.
Nathan Reed