Ok, I’ve made some progress on this, but it’s not quite right yet.
To continue with this soliloquy, my approach is as follows:
- Override GetRenderMatrix()
- Apply Component’s transform to get the world space location, rotation and scale. The default implementation of GetRenderMatrix simply returns this value.
- Apply to the above the inverse transformation of the Camera perspective, to “cancel” out the camera FOV that will be applied at render time
- Apply the transformation for the required FOV.
- Pass this transformation to the renderer.
There’s definitely something happening here, but it’s not quite right.
Can anyone spot the mistake in my math?
// Get references
APWNWeapon* wp = Cast<APWNWeapon>(GetOuter());
// The current camera FOV that we want to remove
float currFovFull = 120.0f;
// The FOV we actually want to apply to the mesh
float requiredFovFull = 115.0f;
pc = Cast<APWNPlayerCharacter>(wp->GetOwner());
// Get current FOV
currFovFull = (Cast<APlayerController>(pc->Controller))->PlayerCameraManager->GetFOVAngle();
// Calc radial FOV to pass into FPerspectiveMatrix
float engineFovHalf = PI / (180.0f / (currFovFull * 0.5f));
float requiredFovHalf = PI / (180.0f / (requiredFovFull * 0.5f));
// Get perspective matrix that will be applied after we send our data and invert it - inversion will allow us to pre-emptively remove the camera FOV
FPerspectiveMatrix enginePerspective = FPerspectiveMatrix(engineFovHalf, 1920.0f, 1080.0f, 1.0f);
FMatrix invEnginePerspective = enginePerspective.Inverse();
// Set up perspective matrix we want to apply
FPerspectiveMatrix requiredPerspective = FPerspectiveMatrix(requiredFovHalf, 1920.0f, 1080.0f, 1.0f);
// Get world transform for this comp and apply inverse and required transforms to it
FMatrix adjTransform = invEnginePerspective * requiredPerspective * ComponentToWorld.ToMatrixWithScale();
This code is definitely transforming the mesh in the sort of way I’m looking for, but the problem is that when I decrease requiredFovFull, the mesh actually seems MORE distorted, which does not make sense to me.