How to obtain the transformation matrix of VTK?

The matrix I obtained through the following method shows that the variable “wcdc” is different from the variable “MCDCMatrix” in the shader

	vtkMatrix4x4* wcdc;
	vtkMatrix4x4* wcvc;
	vtkMatrix3x3* norms;
	vtkMatrix4x4* vcdc;
	vtkOpenGLCamera* cam = (vtkOpenGLCamera*)(renderer->GetActiveCamera());
	cam->GetKeyMatrices(renderer, wcvc, norms, vcdc, wcdc);

Hello @Lincac

If your actor has been translated/scaled/rotated, you’ll need to fetch it’s model-to-world transformation matrix and multiply that with the world-to-display transform in order to get the correct model-to-display matrix.

vtkMatrix4x4* mcdc = nullptr;

vtkMatrix4x4* wcdc = nullptr;
vtkMatrix4x4* wcvc = nullptr;
vtkMatrix3x3* norms = nullptr;
vtkMatrix4x4* vcdc = nullptr;
auto* camera = renderer->GetActiveCamera();
auto* oglCamera= vtkOpenGLCamera::SafeDownCast(camera);
cam->GetKeyMatrices(renderer, wcvc, norms, vcdc, wcdc);
if (!actor->GetIsIdentity())
{
  auto* oglActor = vtkOpenGLActor::SafeDownCast(actor);
  oglActor ->GetKeyMatrices(mcwc, norms);
  vtkMatrix4x4::Multiply4x4(mcwc, wcdc, mcdc);
}
else
{
  mcdc = wcdc;
}

Thank you very much for your reply. In my program, I did not transform the Actor. However, when I used RenderDoc to capture the rendering call of VTk, I found that the data passed into the vertex shader was different from the data I read. Did it perform any other operations internally

basic data

Upload data

It could be possible that the mapper shifted and scaled your coordinates to prevent precision issues in shaders. You can disable that with vtkOpenGLVertexBufferObject::SetGlobalCoordShiftAndScaleEnabled(false) and check the vertexMC values again to confirm the shift scale is causing it.

When a shift scale is applied, the mapper pre-multiplies an internal 4x4 matrix called VBOShiftScale on the mcwc

vtkMatrix4x4::Multiply4x4(VBOShiftScale, mcwc, mcwcShiftedAndScaled);

Unfortunately, there is no easy way to get a pointer to the VBOShiftScale matrix outside the mapper. Here’s a way to compute it yourself.

if (auto* oglMapper = vtkOpenGLPolyDataMapper::SafeDownCast(mapper))
{
  vtkNew<vtkMatrix4x4> VBOShiftScale;
  auto* vbos = oglMapper->GetVBOs();
  posVBO = vbos->GetVBO("vertexMC");
  if (posVBO && 
      posVBO->GetCoordShiftAndScaleEnabled() &&
      !oglMapper->GetPauseShiftScale())
  {
    const auto& shift = posVBO->GetShift();
    const auto& scale = posVBO->GetScale();
    vtkNew<vtkTransform> transform;
    transform->Identity();
    transform->Translate(shift[0], shift[1], shift[2]);
    transform->Scale(1.0 / scale[0], 1.0 / scale[1], 1.0 / scale[2]);
    transform->GetTranspose(VBOShiftScale);
  }
}

Thank you very much for your prompt!Based on your advice, I have found the following interface, which will disable VBO offset

	auto mapper = vtkSmartPointer<vtkOpenGLPolyDataMapper>::New();
	mapper->SetVBOShiftScaleMethod(false);

After using this interface, VBO offset will no longer occur in VTK