Спеціальний шейдер відносності в GLSL


11

Я намагаюся реалізувати шейдер GLSL, який допомагає зрозуміти особливу відносність трансформації Лоренца.

Візьмемо два інерційних спостерігача, вирівняних по осі Oі O'. Спостерігач O'знаходиться в русі WR спостерігача Oзі швидкістю v=(v_x,0,0).

Коли описується в термінах O'координат, подія P' = (x',y',z',ct')перетворила координати(x,y,z,ct)= L (x',y',z',ct')

де L - матриця 4x4 під назвою перетворення Лоренца, яка допомагає нам записувати координати події P 'в Oкоординати.

(детальніше дивіться http://en.wikipedia.org/wiki/Lorentz_transformation#Boost_in_the_x-direction )

Я записав перший попередній шейдер вершин, який застосовує перетворення Лоренца з урахуванням швидкості до кожної вершини, але я не можу змусити перетворення працювати правильно.

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

Цей шейдер повинен застосовуватися до кожної вершини та виконувати нелінійне перетворення Лоренца, але перетворення, яке він виконує, явно відрізняється від того, що я очікував (у цьому випадку - скорочення довжини на осі x).

Хтось уже працював над спеціальним шейдером відносності для 3D відеоігри?


Це насправді лінійна трансформація, а не нелінійна, як зазначено у вікі, яку ви пов’язали. Тож те, що ви бачите, звучить нормально, проте важко сказати точно, не бачачи цього.
Майк Семдер

Ви можете спробувати цей шейдер у ShaderMaker, щоб побачити ефекти, але я хотів би досягти цього ефекту: spacetimetravel.org/relaflug/relaflug.html Тут ми повинні побачити скорочення довжини на осі x, але я бачу неправильне масштабування.
linello

Ви насправді рухаєте камеру? Космічне посилання-посилання має вихідний код, можливо, варто подивитися там
Maik Semder

також швидкість 0,5 с / с трохи невелика, спробуйте скористатися чимось більшим за 0,9, приклад використовує 0,93 с / с і перемістіть камеру з такою швидкістю
Maik Semder

Ні, я припускаю, що спостерігач Oперебуває в (0,0,0) огляді вниз по осі z, тоді як спостерігач O'перебуває в режимі wrt Oзі швидкістю, v_xа описані об'єкти O'знаходяться в спокої. Я знаю, що в цій вершинній шейдері трансформація застосовується тільки для вершин, тому деформація ліній втрачається, але я просто хочу зрозуміти і змусити це спершу працювати. Здається, що гра Polynomial вже зробила подібні трансформації, але шейдер, який я знайшов, нічого не цікавого, тому що я отримую однакові результати! bit.ly/MueQqo
linello

Відповіді:


4

Щоб здійснити стиснення Лоренца, найкраще ставити, мабуть, просто чітко масштабувати об'єкт на 1 / гамму вздовж напрямку руху.

Біда полягає в тому, що перетворення Лоренца зміщує вершини як у часовому напрямку, так і в просторі, тому саме по собі воно не дасть тобі виглядати рухомим об’єктом у конкретний момент часу. Для цього вам слід спочатку перетворити весь об'єкт, а потім провести через нього «фрагмент» паралельно космічним осям, як на цій схемі:

Діаграма простору-часу скорочення Лоренца

Щоб обчислити це за реальним, вам ефективно доведеться прослідкувати в 4D, перетинаючи світову лінію вершини з 3D-площиною поточного моменту часу в системі відліку спостерігача. Я вважаю, що результат цього є таким же, як просто масштабування на 1 / гамма.

(Для додаткового кредиту врахуйте той факт, що спостерігач насправді не побачив би весь об'єкт за один момент часу: він побачив би його за допомогою світлових променів. Тому вам потрібно буде перетинати світову лінію вершина з минулим світловим конусом спостерігача. Це насправді суттєво змінює результати: об’єкт, який відходить від вас, буде виглядати вкороченим, але об’єкт, що рухається до вас, буде здаватися витягнутим, а об’єкт, що рухається в сторону, буде повернутий - див. обертання Пенроуза-Террелла для більш.)


Гаразд, але що робити, якщо я змінюю час всередині моделювання? Я розглядаю час як рівномірний поплавок, що проходить з-за шейдера, це має вчасно деформувати об'єкт?
linello

Якщо час є постійним для кожного кадру, то ви берете тривимірний часовий фрагмент світу 4D, так що так, те, що я сказав вище, має місце.
Натан Рід

Я також не розумію, чи доведеться реалізувати релятивістську аберацію окремо від трансформації Лоренца.
linello

@linello Якщо ви дбаєте про аберацію, то це здається, що вам потрібна більш досконала версія цього я описана в останньому абзаці - тобто перетинати світову лінію вершини з минулим світловим конусом спостерігача та переміщувати вершину до точки перетину просторове розташування. Я думаю, що це повинно бути виконано у вершинній шейдері. Перетворення Лоренца брало б участь лише у встановленні світової лінії вершини. Також зауважте, що якщо об'єкт прискорюється, обертається тощо, то світова лінія вигнута.
Натан Рід
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.