Я пытаюсь реализовать шейдер GLSL, который помогает понять специальное преобразование Лоренца.
Давайте возьмем два ориентированных по оси инерциальных наблюдателя O
и O'
. Наблюдатель O'
движется с наблюдателем 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-видеоигр?
источник
O
в (0,0,0) смотрит вниз по оси z, в то время как наблюдательO'
движетсяO
со скоростью,v_x
а описанные объектыO'
находятся в покое. Я знаю, что в этом вершинном шейдере преобразование применяется только для вершин, поэтому деформация линий теряется, но я просто хочу сначала понять и заставить это работать. Кажется, что игра Polynomial уже произвела преобразования такого рода, но шейдер, который я нашел, не представляет ничего интересного, потому что я получаю те же результаты! bit.ly/MueQqoОтветы:
Чтобы реализовать сжатие Лоренца, лучше всего просто явно масштабировать объект на 1 / гамма вдоль направления движения.
Проблема в том, что преобразование Лоренца смещает вершины как во времени, так и в пространстве, поэтому само по себе оно не даст вам того, как движущийся объект выглядит в определенный момент времени. Чтобы сделать это, вы должны сначала преобразовать весь объект, а затем пройти через него «срез» параллельно пространственным осям, как на этой диаграмме:
Чтобы вычислить это по-настоящему, вам нужно эффективно провести трассировку лучей в 4D, пересекая мировую линию вершины с трехмерной гиперплоскостью текущего момента времени в системе отсчета наблюдателя. Я полагаю, что результат этого будет таким же, как простое масштабирование на 1 / гамма.
(Для дополнительной оценки, примите во внимание тот факт, что наблюдатель фактически не видел бы весь объект в один момент времени: они увидели бы его с помощью световых лучей. Таким образом, вам нужно было бы пересечь мировую линию вершина с последним световым конусом наблюдателя, что на самом деле значительно меняет результаты: объект, удаляющийся от вас, будет выглядеть укороченным, но объект, движущийся к вам, будет выглядеть вытянутым, а объект, движущийся в сторону, будет вращаться - см. вращение Пенроуза-Террелла для большего.)
источник