I'm working on a simulator project. Computer A which uses a stick as a controller to produce operation data and calculate simulate data which will be sent to computer B as camera positions to render the 3D scene. They both run on 60FPS averagely.

The problem is that I found that the frame time cannot be 16.66ms strictly which produces the jerky images. For example, computer A sends the camera position at 15ms (which is means where the camera should be at 15ms). Then computer B receives the data successfully and start to render that frame, but the render time is 18ms (not because the render was too slow I use vSync to limit the FPS but it cannot be strict for every frame). Then the image was swapped at 18ms which should be swapped at 15ms. More importantly, the frame time float around 15ms-18ms, although the average FPS was 60.

Now I'm using interpolation to solve this problem. It has great help, but cannot fix this problem perfectly. Is there a better solution? Thank you for helping me out.

This is part of my code about interpolation.

long long nowTime = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
long long time = firstReceiveTime + nowTime - firstRenderTime;

CameraParamterNode* current = head;
while ((current->next->next != nullptr) && current->next->data->frameTime < time)
    current = current->next;

double diff = static_cast<double>(time - current->data->frameTime) / (current->next->data->frameTime - current->data->frameTime);

pos = (current->next->data->pos - current->data->pos) * diff + current->data->pos;
dir = (current->next->data->dir - current->data->dir) * diff + current->data->dir;
up = (current->next->data->up - current->data->up) * diff + current->data->up;
  • 1
    \$\begingroup\$ Interpolation is indeed the usual fix for this. Want to show us your interpolation implementation, and we can try to suggest improvements/fixes to those specifics? \$\endgroup\$ – DMGregory Jan 23 '19 at 10:20
  • \$\begingroup\$ Thank you for your reply. The Interpolation is simple, I cache 2 frames received data and record the delta time of receiving data and render time. Then I use the render delta time to calculate the interpolation of the received camera data. I added some code to the question. @DMGregory \$\endgroup\$ – Sheldon Wang Jan 24 '19 at 3:39
  • \$\begingroup\$ I would recommend keeping three data points and calculate the current camera using the middle point as the baseline in your interpolation - this will allow you to move forward and backwards in time based on how your clocks match up. Yes, you will always be one frame "behind." I would send a timestamp with each data point because the source intervals will be variable, too. Using that timestamp you will then be able to compare your current rendering time to the data and interpolate your camera position forward or backward to exactly match what the source is telling you. \$\endgroup\$ – Patrick Hughes Jan 24 '19 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.