Rotation + Translate causes camera shakes

Rotation + Translate causes camera shakes

I am running out of ideas of what could be the reason for this, but when i move and rotate the camera an insane lag appers(but it doesnt show of in the FPS, they are always around 120). It doesnt happen when i just rotate the camera or translate it.

Video to show the problem:

https://www.youtube.com/watch?v=3UuXZLzU-As&feature=youtu.be

What could be the reason for this? I tried:

To use raw input, but because it didnt solve it i rolled back.
Rewrite the camera view calculations.

Ill include some code:

View update:

void Camera::UpdateView()
{
    glm::mat4 rotate = glm::mat4_cast(GetRotation());
    glm::mat4 translate = glm::mat4(1.0f);
    translate = glm::translate(translate, -GetPosition());

    Matrices.view = rotate*translate;

    glm::mat4 matInverseView = glm::inverse(Matrices.view);
    forward = glm::normalize(glm::vec3(matInverseView[2]));
    right = glm::normalize(glm::vec3(matInverseView[0]));
}

Pitch and yaw update:

void Camera::ActiveMouseUpdate(Input * input, double deltaTime)
{
    if (input->MouseMoved())
    {
        yaw -= MOUSE_SENSIBILITY * input->GetMouseSpeed().x*deltaTime;
        pitch += MOUSE_SENSIBILITY * input->GetMouseSpeed().y*deltaTime;
        pitch = glm::clamp(pitch, glm::radians(-85.0f), glm::radians(85.0f));
        CalculateComponents();
        cameraChanged = true;
    }

}

Rotation update:

void Camera::CalculateComponents()
{
	glm::quat qPitch = glm::angleAxis(pitch, glm::vec3(1, 0, 0));
	glm::quat qYaw = glm::angleAxis(yaw, glm::vec3(0, 1, 0));
	//For a FPS camera we can omit roll
	glm::quat orientation = glm::normalize(qPitch * qYaw);
	orientation = glm::mix(GetRotation(), orientation, 0.5f);

	//order matters,update camera_quat
	SetRotation(glm::mix(GetRotation(),orientation,0.5f));
}

Movement:

void Camera::PassiveKeyboardUpdate(Input * input, double deltaTime)
{
    cameraChanged = false;

    glm::vec3 pos = GetPosition();

    if (input->isKeyDown(KEY_W))
    {
        pos -= (float)deltaTime*forward*speed;
        cameraChanged = true;
    }
    if (input->isKeyDown(KEY_S))
    {
        pos += (float)deltaTime*forward*speed;
        cameraChanged = true;
    }
    if (input->isKeyDown(KEY_D))
    {
        pos += (float)deltaTime*right*speed;
        cameraChanged = true;
    }
    if (input->isKeyDown(KEY_A))
    {
        pos -= (float)deltaTime*right*speed;
        cameraChanged = true;
    }
}

Mouse input:

	case WM_MOUSEMOVE:
		if (captureWindow)
		{
			mousePosition.x = LOWORD(lParam);
			mousePosition.y = HIWORD(lParam);
			mouseChangeState = true;
			if (forcedMouseMove)
			{
				lastUpdatePosition = mousePosition;
				forcedMouseMove = false;
				mouseChangeState = false;
			}
			else if(glm::abs(mousePosition.x + screen.left - Middle.x ) > 400 || glm::abs(mousePosition.y + screen.top - Middle.y) > 300)
				SetCursorCenter();
		}
		break;

How my loop works:

void CoreEngine::Loop()
{
    while (renderer->Run())
    {
        UpdateFPS();
        UpdateInput();
        Update();
        Draw();
    }
}

Update input:

void CoreEngine::UpdateInput()
{
    input->Update();
    if(input->KeyboardChanged())
        root->ActiveKeyboardUpdate(input, deltaTime);
    root->PassiveKeyboardUpdate(input, deltaTime);
    if (input->MouseChanged())
        root->ActiveMouseUpdate(input, deltaTime);
}

Update:

void CoreEngine::Update()
{
    root->Update(deltaTime,enlapse);
}

Draw:


void CoreEngine::Draw()
{
    renderer->PrepareFrame();
    renderer->Draw();
    renderer->DrawTextOverlay();
    renderer->PresentDraw();
    renderer->UpdateUniformBuffers(false);
}

Root is the root node of my object tree which call all objects(nodes) attached updates, which nodes also call their own nodes updates.

glm::quat orientation = glm::normalize(qPitch * qYaw);
orientation = glm::mix(GetRotation(), orientation, 0.5f);

//order matters,update camera_quat
SetRotation(glm::mix(GetRotation(),orientation,0.5f));

What’s the purpose of the mix here - some sort of orientation smoothing? And did you mean to do it twice?

Do things improve if you remove the interpolations entirely?

[QUOTE=Columbo;42345]What’s the purpose of the mix here - some sort of orientation smoothing? And did you mean to do it twice?

Do things improve if you remove the interpolations entirely?[/QUOTE]

Twice wasnt intended, it was just a try to solve it. If i remove it it is almost the same.

"Twice wasnt intended, it was just a try to solve it. If i remove it it is almost the same. " - Just to check, did you try removing both to see if things improve?

FWIW - I don’t think I can really observe any lag in the youtube video, either it’s an input lag that I don’t notice because I’m not on the controls, or the youtube compression has made it kind of disappear.

One thought occurs though. It’s a common error to modify uniform values before the GPU has finished consuming them. If you’re writing new view matrices over the old view matrices before the GPU has finished reading the old view matrices then you would observe a stutter without affecting the framerate.

You haven’t posted any uniform management code so it’s just a guess really, but if triple buffering your uniforms is not something you’ve thought about yet then it could be the problem. The trick I always use is to rule out this sort of synchronisation error as a cause of a given bug is to shove a vkDeviceWaitIdle immediately after any vkQueueSubmit in my code. I do this purely to help diagnose issues, never check this in because it effectively switches off CPU/GPU concurrency.

[QUOTE=Columbo;42353]"Twice wasnt intended, it was just a try to solve it. If i remove it it is almost the same. " - Just to check, did you try removing both to see if things improve?

FWIW - I don’t think I can really observe any lag in the youtube video, either it’s an input lag that I don’t notice because I’m not on the controls, or the youtube compression has made it kind of disappear.

One thought occurs though. It’s a common error to modify uniform values before the GPU has finished consuming them. If you’re writing new view matrices over the old view matrices before the GPU has finished reading the old view matrices then you would observe a stutter without affecting the framerate.

You haven’t posted any uniform management code so it’s just a guess really, but if triple buffering your uniforms is not something you’ve thought about yet then it could be the problem. The trick I always use is to rule out this sort of synchronisation error as a cause of a given bug is to shove a vkDeviceWaitIdle immediately after any vkQueueSubmit in my code. I do this purely to help diagnose issues, never check this in because it effectively switches off CPU/GPU concurrency.[/QUOTE]

I added the vkDeviceWaitIdle after the submits and it didnt solve it :(. The uniform update is done just after the presentation of the draw:

void CoreEngine::Draw()
{
    renderer->PrepareFrame();
    renderer->Draw();
    renderer->DrawTextOverlay();
    renderer->PresentDraw();
    renderer->UpdateUniformBuffers(false);
}
void Renderer::PresentDraw()
{
	VkPresentInfoKHR present_info = {
		VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,                     // VkStructureType              sType
		nullptr,                                                // const void                  *pNext
		1,                                                      // uint32_t                     waitSemaphoreCount
		&_semaphores.TextOverlay, // const VkSemaphore           *pWaitSemaphores
		1,                                                      // uint32_t                     swapchainCount
		&_swapchain.Handle,                                            // const VkSwapchainKHR        *pSwapchains
		&_image_index,                                           // const uint32_t              *pImageIndices
		nullptr                                                 // VkResult                    *pResults
	};
	ErrorCheck(vkQueuePresentKHR(_queues._present_queue, &present_info));
	ErrorCheck(vkQueueWaitIdle(_queues._present_queue));

}

I am using inmediate present mode, but i changed it to FIFO and the problem is still present but with input lag.

I have found that the problem is just about using the mouse and keyboard at the same time, how can i solve it?

After tons of checks and time, i solved the problem.

Just add


    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

At the beginning of your loop if you have this problem. It will take care of all messages from your inputs before the loop begins solving the problem.