사전 프레임률
개념

프레임률

gabury1고친 사람 github-actions[bot]

프레임률은 움직이는 화면이 1초에 몇 번 새 그림으로 바뀌는지를 셉니다. 움직이는 화면은 멈춘 그림을 빠르게 갈아 끼워 만듭니다. 이 수가 높을수록 움직임이 매끄럽게 보입니다. 대신 그림 한 장을 그려 낼 시간이 그만큼 짧아집니다.

쉽고 빠른 이해

프레임률은 화면이 1초에 새 그림으로 몇 번 바뀌는지를 세는 값입니다. 1초에 그림 60장이 지나가면 프레임률은 60입니다.

이 값이 있어야 「얼마나 매끄러운가」를 숫자로 말할 수 있습니다. 목표를 60으로 잡으면 한 장을 60분의 1초 안에 끝내야 한다는 시간 한도도 함께 나옵니다.

어떻게 도는가:

  1. 프로그램이 그림 한 장을 그립니다
  2. 다 그린 그림을 화면에 내보냅니다
  3. 곧바로 다음 장을 그립니다. 1초 동안 이 일을 몇 번 했는지가 프레임률입니다

대가는 계산입니다. 프레임률을 두 배로 올리면 1초에 그릴 장수도 두 배가 됩니다. 그리고 평균 프레임률은 가끔 한 장이 오래 걸려 생기는 끊김을 가립니다.

상세

종이 뭉치 모서리에 그림을 한 장씩 조금씩 다르게 그려 둡니다. 엄지로 빠르게 넘기면 그림이 움직입니다. 천천히 넘기면 한 장 한 장이 따로 보입니다. 빨리 넘길수록 움직임이 부드러워집니다.

화면의 움직임도 같은 방식으로 만듭니다. 멈춘 그림을 빠르게 갈아 끼워 보여 줍니다. 이 멈춘 그림 한 장이 프레임입니다. 프레임률(frame rate)은 1초에 프레임이 몇 장 바뀌는지를 센 값입니다.

단위는 FPS(frames per second, 초당 프레임 수)입니다. 1초에 60장이 바뀌면 60 FPS 라고 적습니다. 게임과 화면 애니메이션과 녹화된 영상이 모두 이 값으로 매끄러움을 잽니다.

이 값이 있어야 매끄러움을 숫자로 다룰 수 있습니다. 끊겨 보이는지는 보는 사람의 느낌입니다. 프레임률은 재고 견주고 목표로 삼을 수 있습니다. 목표가 서면 그림 한 장에 쓸 수 있는 시간도 정해집니다.

이 절은 먼저 프레임률을 한 장당 시간으로 바꿔 봅니다. 그다음 평균 프레임률이 무엇을 가리는지, 모니터가 화면을 새로 칠하는 횟수와 어떻게 맞물리는지 봅니다. 이어서 영상과 게임이 이 값을 어떻게 다르게 다루는지, 게임이 움직임 계산을 프레임률에서 어떻게 떼어 놓는지 봅니다. 끝으로 프레임률을 끌어내리는 병목과 일부러 거는 상한을 봅니다.

프레임률과 프레임 시간

프레임률을 뒤집으면 한 장에 걸리는 시간이 나옵니다. 이 시간을 프레임 시간(frame time)이라고 부릅니다. 1초, 곧 1000밀리초를 프레임률로 나누면 됩니다.

아래 표는 흔히 쓰는 프레임률마다 한 장에 쓸 수 있는 시간을 적은 것입니다.

프레임률 한 장당 시간 (밀리초)
24 FPS 41.7
30 FPS 33.3
60 FPS 16.7
120 FPS 8.3
144 FPS 6.9

표에서 보듯 둘은 반비례합니다. 프레임률이 두 배가 되면 한 장에 쓸 시간은 반이 됩니다.

게임을 만드는 쪽은 이 시간을 한도로 씁니다. 60 FPS 가 목표면 입력 읽기와 상태 갱신과 그리기가 전부 16.7밀리초 안에 들어가야 합니다. 이 한도가 프레임 예산(frame budget)입니다. 한도를 넘는 장이 나오면 그만큼 프레임률이 떨어집니다.

반비례라서 프레임률을 똑같이 10 올려도 줄어드는 시간이 다릅니다. 30 에서 40 으로 올리면 한 장당 시간이 33.3밀리초에서 25.0밀리초로 8.3밀리초 줄어듭니다. 60 에서 70 으로 올리면 16.7밀리초에서 14.3밀리초로 2.4밀리초만 줄어듭니다. 그래서 성능을 견줄 때는 프레임률보다 프레임 시간이 공평합니다.

평균이 가리는 끊김

프레임률은 대개 1초 동안 그린 장수를 세어 냅니다. 그래서 1초 안에서 한 장이 유난히 오래 걸려도 합계에 묻힙니다.

예를 들어 1초 동안 59장은 16밀리초씩 걸리고 한 장만 56밀리초가 걸렸다고 합시다. 모두 더하면 딱 1초에 60장이라 프레임률은 60입니다. 그런데 그 한 장을 기다리는 56밀리초 동안 화면은 멈춰 있었습니다. 보는 사람은 이 멈춤을 끊김(stutter)으로 느낍니다.

매끄러움을 제대로 보려면 프레임 시간을 한 장씩 늘어놓고 봅니다. 가장 오래 걸린 1% 의 프레임만 따로 모아 그 시간을 적는 방식이 흔합니다.

이 값은 백분위수로 적습니다. 프레임 시간을 짧은 것부터 줄 세웠을 때 99% 지점에 오는 값이 99번째 백분위수입니다. 100장이면 이보다 오래 걸린 장이 한 장뿐인 시간입니다.

백엔드에서 응답 시간을 평균 대신 백분위수로 보는 것과 같은 까닭입니다. 드물게 오래 걸린 요청이 꼬리 지연이듯 드물게 오래 걸린 프레임이 끊김입니다.

프레임률과 주사율

프레임률은 그리는 쪽의 수입니다. 그림을 보여 주는 모니터에도 따로 정해진 수가 있습니다. 모니터가 1초에 화면을 몇 번 새로 칠하는지를 주사율(refresh rate)이라고 합니다. 단위는 Hz(hertz, 헤르츠)입니다.

60 Hz 모니터는 1초에 화면을 60번 새로 칠합니다. 그리는 쪽이 1초에 100장을 그려도 새로 칠하는 횟수는 60번을 넘지 못합니다. 남는 장은 온전한 한 장으로 보이지 못합니다. 그래서 눈에 보이는 매끄러움은 프레임률과 주사율 가운데 작은 쪽에 묶입니다.

두 수가 어긋나면 화면이 찢어져 보일 수 있습니다. 모니터는 화면을 위에서 아래로 차례로 칠합니다. 칠하는 도중에 새 그림이 들어오면 위쪽은 앞 장이고 아래쪽은 새 장인 화면이 한 번 보입니다. 이 결함을 화면 찢어짐(tearing)이라고 부릅니다.

수직 동기화(vertical synchronization)는 이 찢어짐을 막습니다. 새 그림을 모니터가 한 번 다 칠하고 다음 칠하기를 시작하기 직전에만 바꿔 끼웁니다. 그 순간 전에 다 그린 그림은 기다립니다.

대가는 기다림입니다. 60 Hz 화면에서 한 장이 16.7밀리초를 조금이라도 넘기면 다음 바꿔 끼울 때까지 한 번 더 기다립니다. 그 장은 33.3밀리초 만에 화면에 나옵니다. 그 순간만 보면 프레임률이 30 으로 떨어진 것과 같습니다.

기다림은 반응도 늦춥니다. 버튼을 누른 뒤 그 결과가 화면에 나타나기까지 걸리는 시간을 입력 지연(input lag)이라고 합니다. 그림이 바꿔 끼울 때를 기다리는 만큼 이 시간이 늘어납니다.

거꾸로 모니터가 그림을 기다리는 방식도 있습니다. 새 그림이 도착할 때마다 그때 새로 칠합니다. 이 방식이 가변 주사율(variable refresh rate)입니다. 모니터가 따라갈 수 있는 주사율 범위 안에서는 찢어짐과 기다림을 함께 피합니다.

영상의 프레임률과 게임의 프레임률

녹화한 영상은 프레임률이 파일에 정해져 있습니다. 찍을 때 1초에 몇 장을 담았는지가 재생할 때 1초에 보여 줄 장수가 됩니다. 영화는 오랫동안 1초에 24장을 써 왔습니다.

24장으로도 영화가 매끄럽게 보이는 데는 까닭이 있습니다. 카메라는 한 장을 찍는 동안 짧은 시간에 걸쳐 빛을 모읍니다. 그사이 움직인 물체는 번져서 찍힙니다.

이 번짐이 모션 블러(motion blur)입니다. 번짐이 장과 장 사이의 빈틈을 메워 줍니다. 그래서 적은 장수로도 움직임이 이어져 보입니다.

게임이 그리는 한 장은 한 순간을 멈춰 세운 그림입니다. 번짐을 따로 흉내 내지 않으면 장 사이를 이어 줄 것이 없습니다. 그래서 같은 24장이면 게임은 뚝뚝 끊겨 보입니다. 게임과 화면 애니메이션이 30 이나 60 처럼 더 높은 수를 목표로 잡는 까닭입니다.

게임의 프레임률은 고정되어 있지도 않습니다. 영상은 이미 만든 장을 틀기만 합니다. 게임은 장마다 그때그때 새로 그립니다. 그릴 것이 많은 장면에서는 한 장이 오래 걸립니다. 그만큼 프레임률이 떨어집니다.

게임에서는 높은 프레임률이 반응 속도에도 이어집니다. 한 장이 빨리 나오면 입력이 화면에 반영되기까지 기다리는 시간도 짧아집니다.

프레임률에 묶이지 않는 게임 로직

게임은 한 바퀴에 한 장씩 그리는 반복문 위에서 돕니다. 이 반복문을 게임 루프(game loop)라고 합니다. 한 바퀴는 네 단계입니다. 앞서 프레임 예산에서 본 입력 읽기, 상태 갱신, 그리기에 화면에 내보내기가 더해집니다.

flowchart TD
    A[입력 읽기] --> B[상태 갱신]
    B --> C[그리기]
    C --> D[화면에 내보내기]
    D -->|다음 바퀴| A

그림의 고리를 1초에 몇 바퀴 도느냐가 곧 프레임률입니다. 고리 한 바퀴가 프레임 하나를 내보냅니다.

상태 갱신에서 한 바퀴에 움직일 양을 고정해 두면 문제가 생깁니다. 캐릭터가 한 바퀴에 5칸씩 간다면 60 FPS 컴퓨터에서는 1초에 300칸을 갑니다. 30 FPS 컴퓨터에서는 150칸밖에 못 갑니다. 같은 게임이 기계마다 다른 빠르기로 돌게 됩니다.

이 문제는 지난 바퀴부터 흐른 시간을 곱해서 풉니다. 이 시간이 델타 타임(delta time)입니다. 코드에서는 dt 로 적습니다. 속도는 「한 바퀴에 몇 칸」 대신 「1초에 몇 칸」으로 정해 둡니다. 매 바퀴 거기에 dt 를 곱해 그 바퀴에 움직일 양을 구합니다.

아래 코드는 두 방식을 나란히 둔 것입니다. 오른쪽 주석이 프레임률마다 1초에 가는 거리입니다.

// 고정: 한 바퀴에 5칸
x += 5;          // 60 FPS → 초당 300칸
                 // 30 FPS → 초당 150칸

// dt: 지난 바퀴부터 흐른 초
x += 300 * dt;   // 60 FPS → 초당 300칸
                 // 30 FPS → 초당 300칸

아래쪽은 프레임률이 낮으면 한 바퀴에 더 멀리 갑니다. 60 FPS 에서는 한 바퀴에 5칸, 30 FPS 에서는 10칸입니다. 그래서 어느 컴퓨터에서든 1초에 가는 거리가 300칸으로 같습니다.

물리 계산처럼 매번 같은 간격으로 돌아야 하는 일도 있습니다. 간격이 들쭉날쭉하면 같은 입력에도 결과가 달라지기 때문입니다. 이런 일은 그리기와 떼어 내서 1초에 정해진 횟수만큼만 돌립니다. 이 방식이 고정 타임스텝(fixed timestep)입니다.

프레임률을 정하는 병목

한 장을 내보내려면 두 장치가 일합니다. CPU(Central Processing Unit, 중앙 처리 장치)는 게임 상태를 계산합니다. 그다음 무엇을 그릴지 목록을 만듭니다. 그 목록은 GPU(Graphics Processing Unit, 그래픽 처리 장치)로 넘어갑니다.

GPU 는 그 목록을 받아 화면의 점 하나하나에 색을 칠합니다. 이 점 하나가 픽셀입니다.

두 장치는 동시에 일합니다. GPU 가 앞 장을 칠하는 동안 CPU 는 다음 장을 준비합니다. 그러니 한 장의 시간은 두 일의 합이 아닙니다. 둘 가운데 일이 더 오래 걸리는 쪽이 한 장의 시간을 정합니다.

GPU 쪽 일이 오래 걸려 프레임률이 막힌 상태를 GPU 바운드라고 합니다. 이때는 칠할 픽셀 수를 줄이면 프레임률이 오릅니다. 화면을 이루는 픽셀 수인 해상도를 낮추는 것이 흔한 처방입니다.

CPU 쪽 일이 오래 걸리는 상태는 CPU 바운드라고 합니다. 이때는 해상도를 낮춰도 프레임률이 거의 안 오릅니다. 계산할 것이나 GPU 에 넘길 목록을 줄여야 합니다.

프레임률 상한

프레임률을 끝없이 올리는 것이 늘 이득은 아닙니다. 주사율을 넘겨 그린 장은 화면에 온전히 나오지 못합니다. 그래도 그리는 데 드는 계산과 전력은 그대로 나갑니다.

그러니 프레임률에 위쪽 한도를 걸어 두는 경우가 많습니다. 이 한도를 프레임률 상한(frame rate cap)이라고 부릅니다. 모니터 주사율에 맞추거나 30 처럼 더 낮게 잡습니다. 배터리로 도는 휴대 기기는 이렇게 전기와 열을 아낍니다.

관련 항목

프레임률을 한 장당 시간으로 바꿔 보는 지표

프레임 시간 · 프레임 예산 · 프레임 페이싱 · 백분위수 · 꼬리 지연 · 프레임 드롭

프레임률과 맞물려 화면 표시를 정하는 기술

주사율 · 수직 동기화 · 티어링 · 가변 주사율 · 더블 버퍼링 · 트리플 버퍼링 · 프레임버퍼 · 입력 지연

프레임률을 끌어내리는 병목과 그 처방

GPU 바운드 · CPU 바운드 · 드로 콜 · 오버드로 · 해상도 · 해상도 스케일링 · 업스케일링 · CPU · GPU

게임 상태 갱신을 프레임률에서 떼어 놓는 기법

게임 루프 · 델타 타임 · 고정 타임스텝 · 물리 스텝 · 틱 · 보간

녹화 영상에서 프레임률과 함께 다루는 개념

모션 블러 · 셔터 속도 · 비디오 코덱 · 비트레이트 · 프레임 보간

프레임률을 세는 단위와 보여 주는 장치

프레임 · 헤르츠 · 모니터 · 디스플레이 · 픽셀

프레임률을 목표로 삼는 상위 분야

렌더링 · 렌더 파이프라인 · 게임 개발 · 애니메이션 · 그래픽스 · 비디오

다른 이름: frame rate · FPS · frames per second · 초당 프레임 수 · 프레임 레이트 · 프레임 속도