# 2D Camera Movement Temporal Reprojection

Having an Orthographic Camera with its View Projection Matrix given from the current and last frame, how to reproject the previous frame to the new one?

• Does the camera rotate between frames, or only translate / change in size? (I ask because orthographic cameras are often used in 2D settings where panning/zooming are more common than rotating the camera) Sep 9, 2018 at 19:10
• @DMGregory as of right now it doesn't rotate and i don't think i ever will rotate so it should be fine without. did not specify it because i assumed that there is a matrix based trick out there Sep 9, 2018 at 21:26
• There is, but the reprojection is even easier if there's no rotation, because then it's just a 2D scale & shift, and we don't even need depth information. Sep 9, 2018 at 21:32
• @DMGregory well for now without should do just fine but in the future i need to tackle rotation as well but around z axis only so no depth needed (in theory) Sep 9, 2018 at 21:54

## 3 Answers

Some years late I needed it again and finally solved it. For some reason the translation was inversed so I fixed that by inversing the scale but it shouldn't be needed

float2 halfRes = ((float2)texResolution - 1f) * 0.5f;
float4x4 ndc = float4x4.TRS(new float3(halfRes, 0f), quaternion.identity, new float3(-halfRes, 1f));
float4x4 projMat= mul(ndc, mul(_camera.projectionMatrix, _camera.worldToCameraMatrix));

float4x4 reprojMat = mul(previous, inverse(projMat));
previous = projMat;


and in shader simply

float2 oldPos = mul(ReprojectMatrix, float4(pos, 0, 1)).xy


currently i'm tracking the separate camera data and calculating a reprojection matrix like this (dirty "just make it work" code)

    Vector3 pos = cam.transform.position;
Vector3 diff = lastPos - pos; // pos delta
diff = Vector3.Scale(diff, new Vector3(1f / (cam.orthographicSize * 2f * cam.aspect), 1f / (cam.orthographicSize * 2f), 1f)); // world to uv scale
float relscale = cam.orthographicSize / lastsize;
float relrot = cam.transform.eulerAngles.z - lastrot; // needs aspect ratio correction in shader then maybe it works
Matrix4x4 reprojectmat = Matrix4x4.TRS(-diff, Quaternion.Euler(0f, 0f, relrot), new Vector3(relscale, relscale, 1f));


and in the shader a simply edit the uv by the created matrix

    uv = mul(_Reprojection, float4(uv - 0.5, 0.0, 1.0)).xy + 0.5; // -/+ 0.5 to center scale / rotation


this works for translation and scaling right now (not for rotation) but is for sure not the best way to do it

Im not sure is worth for u or not but at least try once unity cinemachine asset.. Cinemachine

After important try 2d camera.

For more information plz check this breakeys tutorial. enter link description here

• sorry but how does this help me? cinemachine is just controlling the camera and does nothing else that has to do reprojecting the last frame Sep 17, 2018 at 12:24
• whilst any attempt to help answer a question should be welcomed, please ensure you are offering help specific to the question. Otherwise this can lead to needless confusion for both the asker and others reading the information in future. Also, where possible please give a better description of how a tool you mention is used to achieve the desired functionality, rather than just saying 'take a look at xyz asset in Store" etc. Unfortunately I don't have a clue how to answer the question either but if you are not sure, then it is almost always better to leave the answering to somebody else. Sep 17, 2018 at 14:04