사전 시저 테스트
개념

시저 테스트

gabury1고친 사람 github-actions[bot]

시저 테스트는 화면에 정한 사각형 하나 밖으로는 색이 못 나가게 막는 검사입니다. 사각형을 넘는 부분은 가위로 오린 듯 잘려 나갑니다. 앱 화면에서 스크롤되는 목록처럼 그릴 범위가 사각형으로 정해진 장면에 씁니다.

쉽고 빠른 이해

시저 테스트는 화면 위의 사각형 하나를 기준으로 그 안의 픽셀만 칠하게 하는 검사입니다. 앱 화면에 스크롤되는 목록이 있다면, 목록 글자가 목록 테두리를 넘는 부분은 한 점도 안 찍힙니다.

이게 없으면 그리기를 시키는 애플리케이션이 도형을 직접 잘라야 합니다. 테두리에 걸친 글자와 그림마다 넘는 부분을 계산해 오려 낸 뒤에 넘겨야 합니다.

도는 순서는 이렇습니다.

  1. 그리기 전에 사각형의 한 모서리 좌표와 너비·높이를 정합니다
  2. 도형이 픽셀 단위로 쪼개지면 픽셀마다 좌표가 사각형 안인지 봅니다
  3. 사각형 밖의 픽셀은 색을 계산하기 전에 버립니다

대가는 모양의 제약입니다. 화면의 가로세로에 나란한 사각형만 걸 수 있습니다. 기울어진 사각형이나 둥근 모서리는 이 검사로 못 오립니다. 그런 모양은 메모리를 더 쓰는 다른 검사가 맡습니다.

상세

그릴 범위를 사각형으로 정하는 일

기차 창밖의 풍경은 창틀 안에서만 보입니다. 바깥 풍경이 아무리 넓어도 창틀 밖은 벽입니다. 기차가 달려 풍경이 바뀌어도 보이는 범위는 창틀이 정합니다.

화면에 그릴 때도 이런 창틀을 세우는 일이 잦습니다. 앱의 스크롤 목록, 게임 화면 구석의 작은 지도, 둘로 나눈 화면의 한쪽이 그렇습니다. 그리는 내용은 테두리를 넘기도 합니다. 그래도 보여야 하는 것은 테두리 안뿐입니다.

창틀이 없으면 넘친 것이 옆을 덮습니다. 스크롤 목록을 그리면 위아래로 삐져나온 줄이 머리글이나 버튼 위에 찍힙니다.

화면 그리기는 두 주체가 나눠 맡습니다. 애플리케이션은 무엇을 그릴지 정해 도형을 넘깁니다. GPU(Graphics Processing Unit, 그래픽 처리 장치)는 넘겨받은 도형을 화면에 칠하는 전용 처리 장치입니다.

애플리케이션이 넘침을 직접 막으려면 도형을 잘라야 합니다. 테두리에 걸친 글자와 그림마다 넘는 부분을 구해 오려 낸 뒤에 넘깁니다. 걸친 도형이 많을수록 이 계산이 늘어납니다.

시저 테스트는 이 오려 내기를 GPU 에 맡깁니다. 애플리케이션은 사각형 하나만 알려 줍니다. 도형은 자르지 않은 채 넘깁니다. 이름의 시저(scissor)는 가위라는 뜻입니다.

픽셀 하나를 두고 보는 값

화면은 가로세로로 늘어선 작은 칸으로 이뤄집니다. 이 칸 하나가 픽셀입니다.

도형 하나를 그리면 그 도형이 덮는 픽셀들이 먼저 정해집니다. 픽셀마다 색을 칠하겠다고 나선 후보가 하나씩 생깁니다. 이 후보를 프래그먼트라고 부릅니다. 검사는 프래그먼트 하나마다 한 번씩 돕니다.

시저 테스트가 보는 것은 프래그먼트가 놓인 픽셀의 좌표 하나입니다. 그 좌표가 미리 정한 사각형 안에 드는지 봅니다. 이 사각형을 시저 사각형이라고 부릅니다. 원점에 가까운 모서리 한 점의 좌표와 너비·높이, 이렇게 네 값으로 정합니다.

모서리가 (100, 50) 이고 너비 200, 높이 100 인 시저 사각형을 걸었다고 해 보겠습니다. 가로로는 100 부터 299 까지, 세로로는 50 부터 149 까지가 시저 사각형 안입니다. 너비가 200 이면 100 부터 세어 200 픽셀이라 300 은 밖입니다.

이 시저 사각형에 프래그먼트 셋이 차례로 오면 아래처럼 갈립니다.

프래그먼트의 픽셀 좌표 가로가 안인가 세로가 안인가 판정
(150, 80) ✓ ✓ 통과
(320, 80) ✗ ✓ 탈락
(150, 160) ✓ ✗ 탈락

가로와 세로를 따로 봅니다. 둘 다 안일 때만 통과합니다. 한쪽이라도 벗어나면 그 프래그먼트는 색을 남기지 못합니다.

이 검사에 필요한 값은 시저 사각형의 네 수뿐입니다. 그래서 픽셀마다 따로 적어 둘 메모리가 없어도 돕니다. 프래그먼트를 거르는 다른 두 검사, 깊이 테스트와 스텐실 테스트는 픽셀마다 따로 적힌 값이 있어야 돕니다.

그리기 단계 속의 순서

화면 한 장을 그리는 일은 여러 단계를 차례로 지납니다. 이 단계들의 줄이 그래픽스 파이프라인입니다. 시저 테스트는 그 줄에서 프래그먼트를 거르는 검사 가운데 하나입니다.

이 절에서 볼 것은 시저 테스트가 프래그먼트 셰이더보다 앞에 선다는 점입니다. 프래그먼트 셰이더는 프래그먼트마다 색을 계산하는 GPU 프로그램입니다. 프래그먼트 하나에 한 번씩 돌기 때문에 프래그먼트가 줄면 셰이더도 덜 돕니다.

flowchart TD
    R["래스터화 · 도형이 덮는 픽셀을 골라 프래그먼트를 만든다"] --> S["시저 테스트 · 시저 사각형 밖 프래그먼트를 버린다"]
    S --> F["프래그먼트 셰이더 · 프래그먼트마다 색을 계산한다"]
    F --> T["스텐실 테스트 · 픽셀마다 적힌 표식으로 거른다"]
    T --> D["깊이 테스트 · 앞에 있는 것만 남긴다"]
    D --> B["블렌딩 · 남은 색을 화면에 이미 있던 색과 섞는다"]

그림에서 시저 테스트는 셰이더보다 앞에 섭니다. 시저 사각형 안팎은 픽셀 좌표만 보면 정해지기 때문입니다. 셰이더가 무슨 색을 내든 답이 안 바뀝니다.

그래서 시저 사각형 밖 프래그먼트는 색 계산을 건너뜁니다. 화면을 넓게 덮는 도형을 좁은 시저 사각형 안에 그리면 버려지는 프래그먼트만큼 셰이더가 덜 돕니다.

깊이 테스트는 사정이 다릅니다. 이 검사가 보는 값은 카메라에서 프래그먼트까지의 거리, 곧 깊이 값입니다. 셰이더가 이 거리를 바꿔 쓸 수 있어서, 셰이더가 끝나야 답이 정해지는 경우가 있습니다.

뷰포트와 가르기

시저 사각형과 자주 헷갈리는 것이 뷰포트입니다. 뷰포트도 화면 위의 사각형 하나로 정합니다. 하는 일은 다릅니다.

뷰포트는 그려질 장면 전체를 화면의 어느 사각형에 옮겨 놓을지 정합니다. 이 일은 래스터화보다 앞에서, 도형의 좌표를 화면의 픽셀 좌표로 바꾸는 때에 합니다. 뷰포트를 절반으로 줄이면 장면이 절반 크기로 작아져 그 사각형 안에 들어갑니다.

시저 사각형은 장면을 옮기거나 줄이지 않습니다. 사각형 밖의 픽셀을 버리기만 합니다. 시저 사각형을 절반으로 줄여도 장면 크기는 안 바뀝니다. 한쪽이 잘려 나갈 뿐입니다.

뷰포트 시저 사각형
하는 일 장면을 사각형에 맞춰 옮기고 늘이거나 줄인다 사각형 밖 픽셀을 버린다
사각형을 절반으로 줄이면 장면이 작아진다 장면 크기는 같고 절반이 잘린다
도는 때 래스터화 전, 도형 좌표를 픽셀 좌표로 바꿀 때 래스터화 뒤, 프래그먼트마다

표의 첫 줄이 둘을 가릅니다. 뷰포트는 좌표를 옮기는 일이지 픽셀을 버리는 검사가 아닙니다. 그래서 둘을 흔히 같이 씁니다. 뷰포트로 장면을 옮기고, 같은 사각형을 시저 사각형으로 걸어 그 밖을 막습니다.

시저 테스트를 쓰는 장면

그릴 범위가 사각형으로 먼저 정해지고 그 안만 그리면 되는 장면이면 이 검사가 맞습니다. 흔한 넷은 이렇습니다.

쓰는 곳 시저 사각형으로 잡는 범위 막는 것
스크롤 뷰 목록이 보이는 테두리 목록 줄이 머리글이나 버튼 위로 번지는 것
분할 화면 플레이어 한 명이 쓰는 쪽 화면 한 사람의 장면이 옆 사람 쪽으로 번지는 것
바뀐 부분만 다시 그리기 바뀐 부분을 감싸는 사각형 안 바뀐 픽셀을 다시 칠하는 것
조명 계산 줄이기 광원 하나가 닿는 범위를 감싸는 사각형 빛이 안 닿는 픽셀까지 조명을 계산하는 것

셋째 줄의 사각형이 더티 렉탱글입니다. 화면에서 커서 하나만 깜박였다면 그 커서를 감싼 사각형만 다시 그리면 됩니다.

넷째 줄은 디퍼드 셰이딩에서 흔합니다. 이 방식은 물체를 먼저 다 그립니다. 조명은 그 뒤에 광원마다 픽셀 단위로 따로 계산합니다. 작은 전구 하나가 밝히는 범위는 화면의 일부입니다. 그 범위를 감싼 시저 사각형을 걸면 전구에서 먼 픽셀은 조명 계산을 건너뜁니다.

겹겹이 놓인 사각형

UI(User Interface, 사용자 인터페이스)는 사각형 속에 사각형이 들어가는 구조입니다. 창 안에 패널이 있습니다. 패널 안에는 스크롤 목록이 있습니다.

패널을 스크롤하면 패널 안의 목록도 함께 움직입니다. 목록 사각형의 윗부분이 패널 테두리 위로 올라가면, 그 부분은 목록 안이지만 패널 밖입니다. 이 부분은 안 보여야 합니다.

그래서 목록을 그릴 때 거는 시저 사각형은 목록 사각형이 아니라 목록과 패널이 겹치는 부분입니다. 가로세로에 나란한 사각형 둘이 겹치는 부분은 다시 사각형이라 시저 사각형으로 걸 수 있습니다. 한 겹 들어갈 때마다 이렇게 겹치는 부분을 구하고, 그 겹을 다 그리고 나오면 바깥 시저 사각형으로 되돌립니다.

겹치는 부분은 두 사각형의 네 값끼리 크고 작은 것만 비교하면 나옵니다. 왼쪽 끝은 둘 중 큰 쪽, 오른쪽 끝은 둘 중 작은 쪽을 고르는 식입니다. 겹이 아무리 깊어도 GPU 에 넘기는 것은 마지막에 남은 사각형 하나입니다.

API 로 시저 사각형 걸기

이 절은 애플리케이션이 시저 사각형을 거는 방법과 그때 틀리기 쉬운 두 가지를 봅니다. 애플리케이션은 프로그램 호출로 GPU 에 시저 사각형을 알려 줍니다. 이때 쓰는 함수 묶음이 그래픽 API(Application Programming Interface, 응용 프로그램 인터페이스)입니다.

검사를 안 쓰고 싶을 때의 방법은 API 마다 다릅니다. 어떤 API 는 스위치로 검사를 끕니다. 검사가 늘 켜져 있는 API 에서는 시저 사각형을 화면 전체로 잡아 아무것도 안 버리게 합니다.

화면 좌표의 원점은 API 에 따라 왼쪽 아래이거나 왼쪽 위입니다. 원점을 착각하면 시저 사각형이 위아래로 뒤집힌 곳에 걸립니다. 그러면 목록은 거의 다 잘려 안 보입니다. 목록 가운데 뒤집힌 사각형 안에 든 부분만 찍힙니다.

단위도 틀리기 쉽습니다. 화면 배율은 고해상도 화면에서 UI 를 몇 배로 키워 보이게 하는 값입니다. 시저 사각형은 화면의 실제 픽셀 수로 적습니다. 그런데 UI 는 흔히 화면 배율을 곱하기 전의 좌표로 배치를 잡습니다.

배율을 2 배로 키운 모니터에서 그 좌표를 그대로 넣으면 시저 사각형이 가로세로로 절반씩 줄어듭니다. 넓이로는 4 분의 1 만 남고, 목록의 나머지가 잘려 보입니다.

이 검사로는 안 되는 것

이 검사가 오릴 수 있는 모양은 가로세로에 나란한 사각형 하나뿐입니다. 도형 하나를 그리는 동안 걸리는 시저 사각형도 하나입니다. 그 밖의 모양은 다른 수단이 맡습니다.

오리고 싶은 모양 맡는 수단
가로세로에 나란한 사각형 시저 테스트
기울어진 사각형 · 둥근 모서리 · 아무 모양 스텐실 테스트
떨어진 사각형 둘 사각형마다 따로 그리거나 스텐실 테스트
가장자리가 흐리게 사라지는 테두리 블렌딩

스텐실 테스트는 모양을 가리지 않는 대신 비용이 더 듭니다. 픽셀마다 표식을 담을 메모리가 필요합니다. 표식을 심는 그리기도 한 번 더 돌아야 합니다. 사각형으로 될 일을 스텐실로 하면 그만큼 헛돕니다.

판정은 픽셀마다 통과 아니면 탈락입니다. 시저 사각형 테두리에서 글자가 서서히 옅어지게 하는 효과는 이 검사로 못 만듭니다. 그런 테두리는 투명도를 섞는 블렌딩으로 그립니다.

관련 항목

시저 테스트가 놓이는 처리 단계

그래픽스 파이프라인 · 래스터화 · 프래그먼트 셰이더 · 프래그먼트별 테스트 · 출력 병합기 · 프래그먼트

시저 테스트와 나란히 도는 다른 검사

스텐실 테스트 · 깊이 테스트 · 알파 테스트 · 깊이 경계 테스트 · 픽셀 소유권 테스트 · 얼리 Z

시저 사각형을 적는 좌표계와 화면 영역

시저 사각형 · 뷰포트 · 윈도 좌표 · 픽셀 · 프레임버퍼 · 렌더 타깃 · 화면 배율

시저 테스트 대신 모양을 오려 내는 수단

스텐실 버퍼 · 클리핑 · 클립 평면 · 클리핑 마스크 · 프래그먼트 버리기 · 알파 마스킹

시저 테스트로 범위를 줄이는 화면 기법

스크롤 뷰 · 분할 화면 · 더티 렉탱글 · 디퍼드 셰이딩 · 섀도 맵 아틀라스 · 즉시 모드 GUI

시저 테스트를 제공하는 그래픽 API

OpenGL · Vulkan · Direct3D · Metal · WebGL · WebGPU

시저 테스트가 속하는 상위 분류

그래픽스 · 렌더링 · 실시간 렌더링 · 래스터 그래픽스 · GPU · UI

다른 이름: scissor test · 시저 검사 · 시저링