이 글은 Today I Learn 시리즈의 124번째 기록입니다. (총 125개)

연주해 보니 화면이 끊겨서 원인을 찾고 고친 날. 파티클 설정 두 가지도 손봤다.

느린 이유 찾기

감으로 의심한 곳은 이번에도 범인이 아니었다

배경 이미지를 깔고 음 다섯 개만 눌렀는데 화면이 눈에 띄게 끊겼다. 파티클을 많이 뿌리는 것도 아니었다.

파티클이 무거운 줄 알았는데 아니었다. 조건을 하나씩 바꿔 가며 여러 번 재 보고서야 배경 이미지가 범인인 걸 알았다. 배경만 켜고 재고, 끄고 재고, 파티클 수를 바꿔 가며 재는 식이었다.

앞선 TIL 2에서 계산이 느린지 GPU(화면을 실제로 칠하는 장치)가 밀리는지 가르는 법을 봤다. 우리 코드가 한 장에 쓰는 시간과 FPS(초당 몇 장을 그리는가)를 따로 재는 것이다. 이번엔 그걸로 실제 범인을 잡았다.

배경이 느렸던 이유도 이 구분으로 나왔다. 원본 사진을 화면 크기에 맞춰 매 프레임 다시 줄이고(리샘플) 있었는데, 한 번만 줄여 구워 두고 재사용하게 바꾸니 10프레임이 62프레임이 됐다.

가져갈 건 이것이다. 가르는 법을 알고 있어도 감은 여전히 틀린다. 아는 것과 재 보는 것은 다른 일이다.

한 가지 더 — 개발용으로 돌릴 때와 실제 배포본의 속도가 거의 같았다. “배포본이면 빨라지겠지”가 안 통하는 영역이 있다. 화면을 그리는 일은 대체로 그렇다.

자원을 나눠 쓸 땐 덜 중요한 쪽을 먼저 양보시킨다

배경 문제를 고쳤는데도 공연 출력 창을 켜면 관객 화면이 버벅였다. 창이 둘이면 같은 파티클을 두 번 그리기 때문이라, 파티클을 줄이는 것만으로는 부족했다.

여기서 정한 게 이번 작업에서 제일 마음에 든다. 두 화면의 중요도가 다르다. 관객이 보는 화면은 매끄러워야 하고, 연주자가 곁눈질하는 미리보기는 좀 떨어져도 된다. 그래서 출력 창이 열려 있으면 미리보기를 30fps로 낮추고 그만큼을 관객 화면에 넘기게 했다. 실제로 쳐 보니 미리보기가 느린 건 연주에 아무 지장이 없었다.

한정된 자원을 여럿이 나눠 쓸 때, 모두를 똑같이 깎는 게 공평해 보이지만 대개 답이 아니다. 그중 무엇이 결과물이고 무엇이 과정인지를 먼저 가르고, 과정 쪽을 먼저 양보시키는 게 낫다.

대신 사용자가 모르면 안 된다. 미리보기 속도가 왜 낮은지 화면에 표시했다 — 설정한 값과 실제로 도는 값이 다른 상태를 말없이 두면 나중에 “왜 예전만 못하지”의 원인이 된다.


비슷한 것을 합칠 때

큰 차이가 없어 보이면 대개 한 축의 양 끝이다

파티클 모션 목록을 보다가 「피어오름」과 「상승 후 흐트러짐」이 별로 안 달라 보였다. 둘 다 위로 올라가고 흩어지는 정도만 다른 것 같았다.

실제로 그랬다. 같은 계산에 값만 달랐고, 그래서 하나로 합치고 「흩어짐」 슬라이더를 달았다. 최대로 하면 예전 흐트러짐이 되고, 그 사이 값이 전부 새로 열렸다. 목록은 짧아지고 표현은 늘었다.

기능 목록이 길어질 때 한 번 볼 만하다. 나란히 놓인 두 항목이 “비슷한데 조금 다른” 정도면, 대개 별개가 아니라 한 축의 양 끝이다.

합치면서 다른 손잡이를 침범하면 안 된다

합쳐 놓고 흩어짐을 올려 봤더니 속도가 같이 빨라지는 느낌이었다. 확인해 보니 실제로 그랬다. 옛 흐트러짐이 원래 더 빨랐던 값을 그대로 가져와 흩어짐에 섞어 놓은 것이었다.

속도는 이미 제 슬라이더가 있다. 흩어짐이 속도까지 건드리면 두 슬라이더가 같은 것을 조절하는 셈이라, 원하는 그림을 맞추려면 둘을 번갈아 만져야 한다.

합칠 때는 양 끝을 재현하는 데만 신경 쓰기 쉬운데, 그 과정에서 다른 컨트롤의 영역을 물고 들어오는지 같이 봐야 한다. 각 슬라이더가 책임질 것을 한 문장으로 말할 수 있어야 한다 — 흩어짐은 “가로로 얼마나 벌어지나”고 그게 전부다.

컨트롤이 건드릴 범위를 정해 준다

「폭」을 키우면 파티클이 건반에서 나오는 게 아니라 처음부터 넓게 퍼진 채로 시작했다. 태어나는 자리까지 좌우로 흩뿌리고 있었기 때문이다.

그건 폭이 할 일이 아니다. 파티클은 눌린 건반에서 피어올라야 하고, 폭은 올라가면서 얼마나 벌어지는지를 정해야 한다. 시작 위치를 폭에서 떼어내고 항상 건반 너비 안에서 시작하게 했다.

컨트롤을 만들 때 무엇을 조절할지만 정하기 쉬운데, 무엇은 건드리지 않을지도 같이 정해야 한다. 그게 없으면 값을 키울 때마다 의도하지 않은 것까지 따라 움직인다.


만들기 전에

다음 할 일을 훑다가 부딪히는 지점을 먼저 찾는다

백로그에서 크로마키(특정 색을 투명하게 빼내 다른 영상 위에 합성하는 기법) 항목을 보다가 걸리는 게 떠올랐다. 빼낼 색과 파티클 색이 겹치면 파티클에 구멍이 뚫린다.

찾아보니 생각보다 나빴다. 색을 여러 개 고를 수 있게 해도, 무지개 모드는 모든 색조를 쓰기 때문에 어떤 색을 빼내든 어딘가에서 겹친다. 게다가 발광은 반투명을 겹쳐 칠하는 가산 블렌딩이라, 색이 완전히 안 겹쳐도 파티클 가장자리가 배경색에 물든다(스필).

그래서 이 기능은 “배경색을 고르게 해 주기”로 끝나지 않는다. 어떤 조합이 안 되는지 알려 주는 것까지가 기능이다. 안 그러면 사용자가 공연장에서 처음 알게 된다.

만들기 전에 이걸 알아낸 게 값이 컸다. 다 만들고 나서 발견했으면 구조를 다시 잡아야 했을 것이다. 다음 할 일 목록을 훑을 때 “이걸 만들면 지금 있는 것과 부딪히는 데가 있나”를 한 번 묻는 습관이 남았다.


요약

  • 가르는 법을 알아도 감은 여전히 틀린다 — 조건을 하나씩 바꿔 가며 재는 게 빠르다
  • 자원을 나눠 쓸 땐 모두를 똑같이 깎지 말고, 결과물과 과정을 갈라 과정 쪽을 먼저 양보시킨다
  • 설정한 값과 실제로 도는 값이 다르면 사용자에게 알린다
  • 나란히 놓인 두 기능이 “비슷한데 조금 다르”면 대개 한 축의 양 끝이다
  • 합칠 때 다른 컨트롤의 영역을 물고 들어오는지 본다 — 각 슬라이더는 책임을 한 문장으로 말할 수 있어야 한다
  • 컨트롤은 무엇을 조절할지뿐 아니라 무엇은 건드리지 않을지도 정한다
  • 다음 할 일을 훑을 때 “지금 있는 것과 부딪히나”를 묻는다 — 만들고 나서 알면 구조를 다시 잡아야 한다

Series: Today I Learn

1 C++ 자료형(Data Type) 2 MD5 vs pHash 3 C++에서 함수의 선언과 정의 4 Tkinter padx, pady 5 메모리와 포인터 변수 6 Call by Value, Call by Reference, Call by Pointer 비교 7 const 8 Gemfile — Jekyll 프로젝트의 의존성 파일 9 kramdown-parser-gfm — Jekyll의 GFM 파서 10 파서(Parser) 11 AHU vs OHU 12 I might try it vs I'll try it 뉘앙스 차이 13 SESSION_EXPIRE_AT_BROWSER_CLOSE=True 14 configuration key 15 Git stash vs discard 16 subprocess.Popen으로 Windows 탐색기에 명령어를 전달 17 Post 잔디 분석하기 18 Google Sheets Sync 최적화 19 DSL (Domain Specific Language)과 GPL (General Purpose Language) 20 마크다운 표 그리는 방법 21 쿼리 파라미터(Query Parameter). 기존 QR코드 재활용 22 Django 보안 취약점 점검 및 수정 23 OOP Object-Oriented Programming 객체 지향 프로그래밍 24 Fernet 대칭 암호화 25 Jekyll 코드블록 안의 Liquid 태그 26 insertOnConflictUpdate vs DoUpdate(target) 27 세션 필터 28 아코디언(Accordiaon) UI를 펼친상태로 만들기 29 input의 step 30 Word Cloud 31 Google Sheets를 데이터 버스로(with AppSheet) 32 Django 모델 텍스트 필드 자동 수집 패턴 33 localStorage로 섹션 토글 상태 유지 34 순차 ID 생성(`select_for_update()` + `max()` 조합) 35 역참조 검색과 distinct() 36 xlsx 다운로드와 로딩 오버레이 충돌 37 Android 파일 공유 MIME 타입 38 AssetManifest — Flutter 빌드 타임 asset 목록 런타임 조회 39 UTF-8 BOM과 PowerShell 파일 쓰기 40 소리꽃 KeyBloom TIL 1 41 소리꽃 KeyBloom TIL 2 42 소리꽃 KeyBloom TIL 3 43 메트로놈 Simple Metronome TIL 1 44 소리꽃 KeyBloom TIL 4 45 메트로놈 Simple Metronome TIL 2 46 소리꽃 KeyBloom TIL 5 47 메트로놈 Simple Metronome TIL 3 48 정적 블로그 SEO 정비와 Pagefind 검색 도입 49 메트로놈 Simple Metronome TIL 4 50 안드로이드 AudioTrack 연속 재생, 실측 피커 정렬, 카메라 토치 플래시 51 메트로놈 Simple Metronome TIL 5 52 모래게임 Sandrop TIL 1 53 메트로놈 Simple Metronome TIL 6 54 모래게임 Sandrop TIL 2 55 모래게임 Sandrop TIL 3 56 메트로놈 Simple Metronome TIL 7 57 모래게임 Sandrop TIL 4 58 모래게임 Sandrop TIL 5 59 모래게임 Sandrop TIL 6 60 소리꽃 KeyBloom TIL 6 61 모래게임 Sandrop TIL 7 62 모래게임 Sandrop TIL 8 63 소리꽃 KeyBloom TIL 7 64 모래게임 Sandrop TIL 9 65 소리꽃 KeyBloom TIL 8 66 모래게임 Sandrop TIL 10 67 소리꽃 KeyBloom TIL 9 68 소리꽃 KeyBloom TIL 10 69 소리꽃 KeyBloom TIL 11 70 소리꽃 KeyBloom TIL 12 71 소리꽃 KeyBloom TIL 13 72 온실 GreenHouse TIL 1 73 소리꽃 KeyBloom TIL 14 74 온실 GreenHouse TIL 2 75 소리꽃 KeyBloom TIL 15 76 소리꽃 KeyBloom TIL 16 77 소리꽃 KeyBloom TIL 17 78 소리꽃 KeyBloom TIL 18 79 소리꽃 KeyBloom TIL 19 80 소리꽃 KeyBloom TIL 20 81 로그스톤 상표 셀프 출원 TIL 1 82 소리꽃 KeyBloom TIL 21 83 소리꽃 KeyBloom TIL 22 84 소리꽃 KeyBloom TIL 23 85 소리꽃 KeyBloom TIL 24 86 MiniMacro TIL 1 87 Astro가 무엇인지, 왜 옮기는지 88 MiniMacro TIL 2 89 메트로놈 Simple Metronome TIL 8 90 메트로놈 Simple Metronome TIL 9 91 블로그 Astro 이관 TIL 92 오픈데이 Openday TIL 1 93 오픈데이 Openday TIL 2 94 Unreal Engine MCP TIL 1 95 콘티온 Conti On TIL 11 96 오픈데이 Openday TIL 3 97 오픈데이 Openday TIL 4 98 오픈데이 Openday TIL 5 99 ScorePlayer TIL 1 100 BuildingHub TIL 1 101 ScorePlayer TIL 2 102 BuildingHub TIL 2 103 ScorePlayer TIL 3 104 Unreal Engine MCP TIL 2 105 궁 미로 PalaceMaze TIL 1 106 메트로놈 Simple Metronome TIL 10 107 메트로놈 Simple Metronome TIL 11 108 오픈데이 Openday TIL 6 109 BuildingHub TIL 3 110 Obsidian vault에서 코드만 빼기 — directory junction 111 ScorePlayer TIL 4 112 오픈데이 Openday TIL 7 113 URL은 바뀔 수 있는 것에 묶지 않는다 114 도구는 기능이 아니라 내 일에 맞는지로 고른다 115 돌이키기 힘든 변경은 작게 먼저 확인한다 116 궁 미로 PalaceMaze TIL 3 117 궁 미로 PalaceMaze TIL 2 118 소리꽃 KeyBloom TIL 29 119 오픈데이 Openday TIL 8 120 BuildingHub TIL 4 121 ScorePlayer TIL 5 122 BuildingHub TIL 5 123 MiniMacro TIL 3 124 소리꽃 KeyBloom TIL 30 읽는 중 125 궁 미로 PalaceMaze TIL 4