Shader relativitas khusus dalam GLSL

11

Saya mencoba menerapkan shader GLSL yang membantu memahami relativitas khusus Lorentz Transformation.

Mari kita ambil dua pengamat inersia poros-sejajar Odan O'. Pengamat O'bergerak pengamat Odengan kecepatan v=(v_x,0,0).

Ketika dijelaskan dalam hal O'koordinat, suatu peristiwa P' = (x',y',z',ct')telah mengubah koordinat(x,y,z,ct)= L (x',y',z',ct')

di mana L adalah matriks 4x4 yang disebut transformasi Lorentz yang membantu kita menulis koordinat peristiwa P 'dalam Okoordinat.

(untuk detail lihat http://en.wikipedia.org/wiki/Lorentz_transformation#Boost_in_the_x-direction )

Saya telah menulis shader vertex pendahuluan pertama yang menerapkan transformasi Lorentz mengingat kecepatan untuk setiap vertex, tapi saya tidak bisa mendapatkan transformasi untuk bekerja dengan benar.

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

Shader ini harus berlaku untuk setiap titik dan melakukan transformasi Lorentz non-linear, tetapi transformasi yang dilakukannya jelas berbeda dari yang saya harapkan (dalam hal ini kontraksi panjang pada sumbu x).

Apakah seseorang sudah bekerja pada shader relativitas khusus untuk videogame 3D?

linello
sumber
Ini sebenarnya transformasi linear, bukan non-linear, sebagai wiki yang Anda tautkan. Jadi apa yang Anda lihat kedengarannya ok, namun, sulit untuk mengatakannya tanpa melihatnya.
Maik Semder
Anda dapat mencoba shader ini di ShaderMaker untuk melihat efeknya, tetapi yang ingin saya capai adalah efek ini: spacetimetravel.org/relaflug/relaflug.html Di sini kita akan melihat kontraksi panjang pada sumbu x tetapi saya melihat penskalaan yang salah
linello
Apakah Anda benar-benar menggerakkan kamera? Spacetimetravle-link dilengkapi dengan kode sumber, mungkin layak untuk dilihat di sana
Maik Semder
juga kecepatan 0,5 c / s agak kecil, coba gunakan sesuatu yang lebih besar dari 0,9, contohnya menggunakan 0,93 c / s dan gerakkan kamera dengan kecepatan itu
Maik Semder
Tidak, saya kira pengamat Oberada di (0,0,0) melihat ke bawah sumbu z sementara pengamat O'bergerak Odengan kecepatan v_xdan benda-benda yang dijelaskan untuk O'beristirahat. Saya tahu bahwa dalam vertex shader ini transformasi diterapkan hanya untuk simpul sehingga deformasi garis hilang tetapi saya hanya ingin memahami dan membuat pekerjaan ini pada awalnya. Sepertinya game Polynomial sudah membuat transformasi seperti ini, tetapi shader yang saya temukan tidak ada yang menarik, karena saya mendapatkan hasil yang sama! bit.ly/MueQqo
linello

Jawaban:

4

Untuk menerapkan kontraksi Lorentz, taruhan terbaik Anda mungkin hanya untuk secara eksplisit skala objek dengan 1 / gamma di sepanjang arah gerak.

Masalahnya adalah bahwa transformasi Lorentz menggeser simpul ke arah waktu dan juga di ruang, sehingga dengan sendirinya itu tidak akan memberi Anda seperti apa objek bergerak pada saat tertentu dalam waktu. Untuk melakukan itu, Anda harus terlebih dahulu mengubah seluruh objek kemudian mengambil "iris" melaluinya sejajar dengan sumbu ruang, seperti dalam diagram ini:

Diagram ruang-waktu kontraksi Lorentz

Untuk menghitung ini secara nyata, Anda harus raytrace secara efektif dalam 4D, memotong garis dunia dari vertex dengan hyperplane 3D dari momen waktu saat ini dalam kerangka referensi pengamat. Saya percaya hasil dari melakukan ini sama dengan hanya penskalaan dengan 1 / gamma.

(Untuk kredit tambahan, pertimbangkan fakta bahwa seorang pengamat tidak akan benar-benar melihat seluruh objek pada satu saat dalam waktu: mereka akan melihatnya menggunakan sinar cahaya. Jadi, Anda harus memotong garis dunia dari garis tersebut. vertex dengan kerucut cahaya masa lalu dari pengamat. Ini sebenarnya mengubah hasil secara signifikan: objek bergerak menjauh dari Anda akan terlihat memendek, tetapi objek bergerak ke arah Anda akan tampak memanjang dan objek yang bergerak ke samping akan diputar - lihat rotasi Penrose-Terrell untuk lebih.)

Nathan Reed
sumber
Ok, tapi bagaimana jika saya mengubah waktu di dalam simulasi? Saya memperlakukan waktu sebagai pelampung seragam yang harus dilewati dari luar shader, apakah ini harus merusak objek pada waktunya dengan benar?
linello
Jika waktu adalah konstan untuk setiap frame, maka Anda mengambil sepotong waktu 3D dari dunia 4D, jadi ya, apa yang saya katakan di atas berlaku.
Nathan Reed
Saya tidak mengerti juga jika saya harus menerapkan penyimpangan relativistik secara terpisah dari transformasi Lorentz.
linello
@linello Jika Anda peduli tentang penyimpangan, sepertinya Anda memerlukan versi yang lebih canggih dari ini yang saya jelaskan dalam paragraf terakhir - yaitu, memotong garis dunia titik dengan kerucut cahaya pengamat masa lalu, dan memindahkan titik ke titik persimpangan lokasi spasial. Itu bisa dilakukan di vertex shader, saya pikir. Transformasi Lorentz hanya akan terlibat dalam menyiapkan garis dunia vertex. Juga perhatikan bahwa jika objeknya berakselerasi, berputar, dll. Maka garis-dunia melengkung.
Nathan Reed