Как повернуть переведенную текстуру вокруг ее центра - PullRequest
0 голосов
/ 13 апреля 2020

Я работаю над следующим шейдером, который

  1. переводит (на y)

  2. вращается

  3. повторяется (плитка)

текстура:

uniform sampler2D texture;
uniform vec2 resolution;

varying vec4 vertColor;
varying vec4 vertTexCoord;

uniform float rotation;
uniform float yTranslation;

void main() {
  vec2 repeat = vec2(2, 2);
  vec2 coord = vertTexCoord.st;

  coord.y += yTranslation;

  float sin_factor = sin(rotation);
  float cos_factor = cos(rotation);
  coord += vec2(0.5);
  coord = coord * mat2(cos_factor, sin_factor, -sin_factor, cos_factor) * 0.3;
  coord -= vec2(0.5);

  coord = vec2(mod(coord.x * repeat.x, 1.0f), mod(coord.y * repeat.y, 1.0f));

  gl_FragColor = texture2D(texture, coord) * vertColor;
}

Текущее поведение

Current

Желаемое поведение

Я хочу, чтобы текстура всегда вращалась вокруг центра, независимо от того, как далеко она была переведена.

Desired

Простое изменение порядка шагов приводит к странному поведению. Чего мне не хватает?

1 Ответ

1 голос
/ 14 апреля 2020

Ваша формулировка проблемы в вопросе действительно неверна: Ваш дополнительный комментарий (к удаленному ответу):

У меня есть лодка, которая всегда остается в центре экрана, текстура воды (управляется этим шейдером) под ним движется, чтобы он выглядел так, будто лодка движется. Движение текстуры воды контролируется rotation (для рулевого управления) и yTranslation (для того, насколько далеко лодка переместилась вперед / назад)

дает понять, что вы запрашиваете другая вещь, и подход, описанный в вопросе, просто не решит вашу проблему.

Когда ваша лодка движется и вращается, она в основном будет двигаться по кривой (и вы хотите, чтобы инверсия этой кривой проходила через текстурное пространство). Но ваши 2dof параметры rotation и yTranslation не способны описать кривую. Для вашей задачи нужен как минимум еще один параметр xTranslation - поэтому в конце вам понадобится двухмерный вектор, описывающий положение вашей лодки + угол, описывающий вращение. И вам нужно правильно накапливать эти данные на каждом шаге симуляции:

  • обновлять rotation соответственно
  • вычислять 2D-вектор вашего корабля, который определен текущим rotation
  • масштабируйте его в соответствии со скоростью движения
  • накапливайте его на вектор position.

Затем ваш шейдер просто должен 1. перевести текскорды на position (или -position, что бы вы ни хранили) 2. Поверните вокруг точки поворота (которая постоянна и зависит только от того, как вы выложили свое текстурное пространство)

coord = vec2(mod(coord.x * repeat.x, 1.0f), mod(coord.y * repeat.y, 1.0f));

- это пустая трата циклов ALU графического процессора, TMU уже сделает для вас mod с режимами обтекания GL_REPEAT.

Однако теперь у вас есть вращение, масштабирование и перевод. Так что просто используйте единственную матрицу для всего преобразования texcoord - накопление 2D-позиции, о которой я говорил ранее, может быть легко сделано с помощью матричных представлений. Он также удалит sin и cos из вашего шейдера, что сейчас является еще одной огромной тратой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...