Howto modify the projection matrix

The wiring of the matrix is a bit all over the place - i’ve got a collapsed node in my blueprint which I call ‘The Switchboard’! which rewires and reverses many of the inputs into the matrix. I imagine the matrix was copy/pasted from another project with a different coordinate system.

Well after going off on a journey to “UE4’ify” the coordinate system, I realised I was no longer pinned to the borders and returned to the original setup. I’m now trying to add other screens (one screen per client in multiplayer), but with the apparent restriction of having the physical player’s camera location at the same forward/back coordinate as the screen, I can’t get them to line up edge to edge. Are you doing multiple screens by any chance?

There are a few tweakable parameters missing I think. I’d like an FOV dialer which works - this would help to control this stuff. I guess you could move the cameras around but not the offsets during play?

I’m using it to try to make a virtual TV studio - the idea being that you have the image on a cinema size screen and get the offset based on a studio camera jib. I’m a little off this final point but i’d agree that the fine tuning is frustrating.

I’m working on a TV gameshow where you have a large portrait aspect screen, which at this point looks like the front of a building. Ideally i’d have a cinema type screen in front and above that at 45degs another linked screen so the tv camera can look up into the sky - similarly off-axis projected.

Hello Duke,

i am doing multiple displays and i just got the same problem as you do. Found any solution? its working fine for one screen but in our cave setup the floor screen does not line up with the wall screen. its only a little offset but i can not fix it.

best regards

I would like to collaborae but i only got a little amount of tim srsy .(

Interested in this too.

Hello, the example offaxistest_v3.zip is not working in version 4.14, it does give a lot of compilation errors.
Did someone manage to have this working in new versions of the Engine?
Thanks!
Antonio.

i take a look into it the next time i got some free time. that might be in april, at the earlierst.

Hi people, returning the favor here: I fixed it for 4.14.3 because I needed for a project, it is not well tested yet, but compiles and apparently works: link text

BTW: someone at Epic hate us, he change all the matrices as private members and all the returns are constants, I changed by access the pointers MUAJA

Many thanks ZkarmaKun,
It works like a charm.
Will test it on 4.15 too in short.
Antonio.

Hello,
trying to make this work for two cameras at the same time, so I can project on a floor and a wall from the viewer point of view, which I get from a kinect 2 sensor.

I’ve been going through the code and I see it works by changing the matrix for the viewport… what would be the approach to get 2 cameras with the offaxis matrix?
Should it be possible to use it with a sceneCapture2D and then send it through spout?

Currently I have a project with 2 sceneCapture2D, which sends the render target through spout to the rendering system. But I’m not able to figure out how to apply the matrix to thouse sceneCapture2D.

Any suggestion would be really appreciated!

Antonio.

Hi,

Thanks a lot. I managed to get your example project up ad running and it works fine. However, when I can’t get the same result when I add the OffAxisGameViewportClient class to my game. There were no errors when I was trying to compile the class and I modified the build.cs file of my project to add the dependencies

In the editor, I’ve added a camera to the level and made player 0 auto-possess that. My level blueprint is also identical to yours. I’ve also added a blank C++ game mode class and made that the one that is active in maps and modes.

No errors whatsoever, anywhere in the level blueprint either.

In project settings, I changed the default viewport class to the new C++ Off-Axis viewport class

Could you tell me what I’m missing to get this running?

Cheers,

ULocalPlayer::CalcSceneView() is virtual (at least in 4.16 engine), so now it may be narrowed to overloading this method:

 static void UpdateProjectionMatrix(FSceneView* View, FMatrix PostProjectionMatrix)
   {
   View->ProjectionMatrixUnadjustedForRHI = View->ProjectionMatrixUnadjustedForRHI * PostProjectionMatrix;
 
   FMatrix* pProjectionMatrix = (FMatrix*)(&View->ViewMatrices.GetProjectionMatrix());
   *pProjectionMatrix = AdjustProjectionMatrixForRHI(View->ProjectionMatrixUnadjustedForRHI);
 
   FMatrix* pViewProjectionMatrix = (FMatrix*)(&View->ViewMatrices.GetViewProjectionMatrix());
   *pViewProjectionMatrix = View->ViewMatrices.GetViewMatrix() * View->ViewMatrices.GetProjectionMatrix();
 
   FMatrix* pInvViewProjectionMatrix = (FMatrix*)&View->ViewMatrices.GetInvViewProjectionMatrix();
   *pInvViewProjectionMatrix = View->ViewMatrices.GetViewProjectionMatrix().Inverse();
 
   FMatrix TranslatedViewMatrix = FTranslationMatrix(-View->ViewMatrices.GetPreViewTranslation()) * View->ViewMatrices.GetViewMatrix();
   FMatrix* pTranslatedViewProjectionMatrix = (FMatrix*)(&View->ViewMatrices.GetTranslatedViewProjectionMatrix());
   *pTranslatedViewProjectionMatrix = TranslatedViewMatrix * View->ViewMatrices.GetProjectionMatrix();
 
   FMatrix* pInvTranslatedViewProjectionMatrixx = (FMatrix*)(&View->ViewMatrices.GetInvTranslatedViewProjectionMatrix());
   *pInvTranslatedViewProjectionMatrixx = View->ViewMatrices.GetTranslatedViewProjectionMatrix().Inverse();
 
   View->ShadowViewMatrices = View->ViewMatrices;
 
   GetViewFrustumBounds(View->ViewFrustum, View->ViewMatrices.GetViewProjectionMatrix(), false);
   }
 
 FSceneView* UMyLocalPlayer::CalcSceneView(class FSceneViewFamily* ViewFamily, FVector& OutViewLocation, FRotator& OutViewRotation, FViewport* Viewport, class FViewElementDrawer* ViewDrawer /*= NULL*/, EStereoscopicPass StereoPass /*= eSSP_FULL*/)
   {
   auto View = ULocalPlayer::CalcSceneView(ViewFamily, OutViewLocation, OutViewRotation, Viewport, ViewDrawer, StereoPass);
   if (View)
     {
     FScaleMatrix scaleM(FVector(1.f, PixelAspect, 1.0f));
     FTranslationMatrix shiftM(FVector(CCDOffset.X, CCDOffset.Y, 0.0f));
     UpdateProjectionMatrix(View, scaleM * shiftM);
     }
 
   return View;
   }

Very interesting read! I looked into the code, because I would like to be able to offset each eye in an HMD separately. Would he offaxistest code apply here? Also since we are now at version 4.17/4.18 of the engine, does this still apply or would there be a better approach to get this to work?

ULocalPlayer::CalcSceneView() is virtual (at least in 4.16 engine), so it may be narrowed to overloading this method (see my comment above)

Cool! I am gonna work on a solution (4.17 also uses public virtual functions). Will keep you guys updated (if someone wants to collab, highly appreciated).

Update: I got it working, yet any background texture (plane, 3d widget etc) will also be affected. Since I am trying to find a way to project something on a webcam texture I tried to modify scenecapture2d which does not work yet My question here!

As some guy mentioned showed here it can work. But I couldn’t figure it out yet.

Hey,

I just put up a public repo based on the info here. It contains a working version for UE4.18:

Feel free to collaborate :slight_smile:

Best, Florian

This is great!

Have you had any success in getting it to be able to start at a translation/rotation you pick rather than at 0,0,0? I’ve tried a bunch of things but can’t seem to get it right.

Hi,
I’m not sure what yo mean? Like an initial rotation/translation of the camera? Or placing the viewplane at a different position?
Best,
Florian

Hey everyone, I know the OP is asking for a solution without the use of the LocalPlayer but for those looking for a simple solution for changing the projection matrix using the local player, we have created a quick tutorial and plugin.

Tutorial Link

[Plugin Link][2]

Hope this helps some of you out!