20.5 C
Brasília
domingo, junho 1, 2025

Por que a ordem da matriz de transformação é revertida na minha implementação de gráficos de cena?


Eu pesquisei muito isso e até agora todos os exemplos, tutoriais and so on. sempre use a seguinte ordem: escala * gire * traduza, mas por algum motivo essa ordem deve sempre ser atrasada no meu gráfico de cena. Não tenho certeza se isso se destina devido à transformação da matriz native em matriz mundial ou é um bug inerente ao meu aplicativo.

Aqui está a minha implementação simples de gráfico de cenas. Estou usando a Biblioteca de Matemática Vulkan e Glm.

void SceneNode::setTransform(glm::mat4 rework) {
  transformLocal = rework;
}

void SceneNode::replace() {
  // if root node
  if (parentNode == nullptr) {
    transformWorld = transformLocal;
  } else {
    transformWorld = parent->transformWorld * transformLocal;
  }

  for (auto &node : kids) {
    node->replace();
  }
}

E minha lógica do shader:

// initialization code hidden for simplicity

void principal() {
  // worldTransform = rework matrix calculated throughout scene node replace
  gl_Position = UniformCameraData.projectionView * ModelPushConstants.worldTransform * vec4(vPosition, 1.0f);

  outColor = vColor;
}

Como uma demonstração, criei uma cena tremendous simples com esferas:

Root
  Sphere Middle -> Rotate round its personal axis
    Sphere 1 -> Place someplace close to the father or mother and Rotate round its personal axis
    Sphere 2 -> Place someplace close to the father or mother andRotate round its personal axis
    Sphere 2 -> Place someplace close to the father or mother andRotate round its personal axis

Este gráfico de cena me dá uma esfera no meio que gira e três esferas que giram por serem filhos desta esfera; Além disso, as próprias esferas giram em torno de seu próprio eixo:

Por que a ordem da matriz de transformação é revertida na minha implementação de gráficos de cena?

No entanto, a implementação é silenciosa para mim. A ordem das transformações é traduzida * Gire * escala em vez de o contrário:

child1->setTransform(
          glm::translate(glm::mat4{1.0}, glm::vec3{2.0, 0.0, 0.0}) *
          glm::rotate(glm::mat4{1.0f}, glm::radians(body * 0.9f),
                      glm::vec3{0.0, 0.0, -1.0}) *
          glm::scale(glm::mat4{1.0}, glm::vec3{0.4, 0.4, 0.4}));

// ...different kids transformations

scene->replace();

Quando mudo a ordem das transformações, a rotação acontece ao redor da esfera central:

child1->setTransform(
          glm::rotate(glm::mat4{1.0f}, glm::radians(body * 0.9f),
                      glm::vec3{0.0, 0.0, -1.0}) *
          glm::translate(glm::mat4{1.0}, glm::vec3{2.0, 0.0, 0.0}) *
          glm::scale(glm::mat4{1.0}, glm::vec3{0.4, 0.4, 0.4}));

// ...different kids transformations

scene->replace();

Demonstração - Transformação errada

Como você pode ver, a esfera colorida ciana gira em torno do pai em vez de seu próprio centro.

Fiquei confuso com isso, então, adicionei a tradução ao nó raiz (por exemplo (2.0, 1.0)) e obtive o mesmo resultado. Se eu girar a esfera, traduzir, ela girará contra (0, 0) e depois traduzirá para (2.0, 1.0) ao mesmo tempo, o que significa que está em (2,0, 1,0) e girando contra (0,0, 0,0). Por outro lado, se eu traduzir primeiro, depois girar, ele girará contra (2.0, 1.0) e traduzirá para (2.0, 1.0) ao mesmo tempo, o que significa que está girando contra o centro recém -traduzido.

Logicamente, isso faz sentido para mim porque essas multiplicações estão acontecendo ao mesmo tempo e o resultado é gravado no nó, mas ainda não entendo por que a ordem de transformação tipicamente sugerida é a escala * girar * tradução. Alguém pode me explicar o que estou perdendo aqui que tenho que usar multiplicar transformações está em ordem inversa?

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Stay Connected

0FansLike
0FollowersFollow
0SubscribersSubscribe
- Advertisement -spot_img

Latest Articles