소리꽃 KeyBloom TIL 30
연주해 보니 화면이 끊겨서 원인을 찾고 고친 날. 파티클 설정 두 가지도 손봤다.
느린 이유 찾기
감으로 의심한 곳은 이번에도 범인이 아니었다
배경 이미지를 깔고 음 다섯 개만 눌렀는데 화면이 눈에 띄게 끊겼다. 파티클을 많이 뿌리는 것도 아니었다.
파티클이 무거운 줄 알았는데 아니었다. 조건을 하나씩 바꿔 가며 여러 번 재 보고서야 배경 이미지가 범인인 걸 알았다. 배경만 켜고 재고, 끄고 재고, 파티클 수를 바꿔 가며 재는 식이었다.
앞선 TIL 2에서 계산이 느린지 GPU(화면을 실제로 칠하는 장치)가 밀리는지 가르는 법을 봤다. 우리 코드가 한 장에 쓰는 시간과 FPS(초당 몇 장을 그리는가)를 따로 재는 것이다. 이번엔 그걸로 실제 범인을 잡았다.
배경이 느렸던 이유도 이 구분으로 나왔다. 원본 사진을 화면 크기에 맞춰 매 프레임 다시 줄이고(리샘플) 있었는데, 한 번만 줄여 구워 두고 재사용하게 바꾸니 10프레임이 62프레임이 됐다.
가져갈 건 이것이다. 가르는 법을 알고 있어도 감은 여전히 틀린다. 아는 것과 재 보는 것은 다른 일이다.
한 가지 더 — 개발용으로 돌릴 때와 실제 배포본의 속도가 거의 같았다. “배포본이면 빨라지겠지”가 안 통하는 영역이 있다. 화면을 그리는 일은 대체로 그렇다.
자원을 나눠 쓸 땐 덜 중요한 쪽을 먼저 양보시킨다
배경 문제를 고쳤는데도 공연 출력 창을 켜면 관객 화면이 버벅였다. 창이 둘이면 같은 파티클을 두 번 그리기 때문이라, 파티클을 줄이는 것만으로는 부족했다.
여기서 정한 게 이번 작업에서 제일 마음에 든다. 두 화면의 중요도가 다르다. 관객이 보는 화면은 매끄러워야 하고, 연주자가 곁눈질하는 미리보기는 좀 떨어져도 된다. 그래서 출력 창이 열려 있으면 미리보기를 30fps로 낮추고 그만큼을 관객 화면에 넘기게 했다. 실제로 쳐 보니 미리보기가 느린 건 연주에 아무 지장이 없었다.
한정된 자원을 여럿이 나눠 쓸 때, 모두를 똑같이 깎는 게 공평해 보이지만 대개 답이 아니다. 그중 무엇이 결과물이고 무엇이 과정인지를 먼저 가르고, 과정 쪽을 먼저 양보시키는 게 낫다.
대신 사용자가 모르면 안 된다. 미리보기 속도가 왜 낮은지 화면에 표시했다 — 설정한 값과 실제로 도는 값이 다른 상태를 말없이 두면 나중에 “왜 예전만 못하지”의 원인이 된다.
비슷한 것을 합칠 때
큰 차이가 없어 보이면 대개 한 축의 양 끝이다
파티클 모션 목록을 보다가 「피어오름」과 「상승 후 흐트러짐」이 별로 안 달라 보였다. 둘 다 위로 올라가고 흩어지는 정도만 다른 것 같았다.
실제로 그랬다. 같은 계산에 값만 달랐고, 그래서 하나로 합치고 「흩어짐」 슬라이더를 달았다. 최대로 하면 예전 흐트러짐이 되고, 그 사이 값이 전부 새로 열렸다. 목록은 짧아지고 표현은 늘었다.
기능 목록이 길어질 때 한 번 볼 만하다. 나란히 놓인 두 항목이 “비슷한데 조금 다른” 정도면, 대개 별개가 아니라 한 축의 양 끝이다.
합치면서 다른 손잡이를 침범하면 안 된다
합쳐 놓고 흩어짐을 올려 봤더니 속도가 같이 빨라지는 느낌이었다. 확인해 보니 실제로 그랬다. 옛 흐트러짐이 원래 더 빨랐던 값을 그대로 가져와 흩어짐에 섞어 놓은 것이었다.
속도는 이미 제 슬라이더가 있다. 흩어짐이 속도까지 건드리면 두 슬라이더가 같은 것을 조절하는 셈이라, 원하는 그림을 맞추려면 둘을 번갈아 만져야 한다.
합칠 때는 양 끝을 재현하는 데만 신경 쓰기 쉬운데, 그 과정에서 다른 컨트롤의 영역을 물고 들어오는지 같이 봐야 한다. 각 슬라이더가 책임질 것을 한 문장으로 말할 수 있어야 한다 — 흩어짐은 “가로로 얼마나 벌어지나”고 그게 전부다.
컨트롤이 건드릴 범위를 정해 준다
「폭」을 키우면 파티클이 건반에서 나오는 게 아니라 처음부터 넓게 퍼진 채로 시작했다. 태어나는 자리까지 좌우로 흩뿌리고 있었기 때문이다.
그건 폭이 할 일이 아니다. 파티클은 눌린 건반에서 피어올라야 하고, 폭은 올라가면서 얼마나 벌어지는지를 정해야 한다. 시작 위치를 폭에서 떼어내고 항상 건반 너비 안에서 시작하게 했다.
컨트롤을 만들 때 무엇을 조절할지만 정하기 쉬운데, 무엇은 건드리지 않을지도 같이 정해야 한다. 그게 없으면 값을 키울 때마다 의도하지 않은 것까지 따라 움직인다.
만들기 전에
다음 할 일을 훑다가 부딪히는 지점을 먼저 찾는다
백로그에서 크로마키(특정 색을 투명하게 빼내 다른 영상 위에 합성하는 기법) 항목을 보다가 걸리는 게 떠올랐다. 빼낼 색과 파티클 색이 겹치면 파티클에 구멍이 뚫린다.
찾아보니 생각보다 나빴다. 색을 여러 개 고를 수 있게 해도, 무지개 모드는 모든 색조를 쓰기 때문에 어떤 색을 빼내든 어딘가에서 겹친다. 게다가 발광은 반투명을 겹쳐 칠하는 가산 블렌딩이라, 색이 완전히 안 겹쳐도 파티클 가장자리가 배경색에 물든다(스필).
그래서 이 기능은 “배경색을 고르게 해 주기”로 끝나지 않는다. 어떤 조합이 안 되는지 알려 주는 것까지가 기능이다. 안 그러면 사용자가 공연장에서 처음 알게 된다.
만들기 전에 이걸 알아낸 게 값이 컸다. 다 만들고 나서 발견했으면 구조를 다시 잡아야 했을 것이다. 다음 할 일 목록을 훑을 때 “이걸 만들면 지금 있는 것과 부딪히는 데가 있나”를 한 번 묻는 습관이 남았다.
요약
- 가르는 법을 알아도 감은 여전히 틀린다 — 조건을 하나씩 바꿔 가며 재는 게 빠르다
- 자원을 나눠 쓸 땐 모두를 똑같이 깎지 말고, 결과물과 과정을 갈라 과정 쪽을 먼저 양보시킨다
- 설정한 값과 실제로 도는 값이 다르면 사용자에게 알린다
- 나란히 놓인 두 기능이 “비슷한데 조금 다르”면 대개 한 축의 양 끝이다
- 합칠 때 다른 컨트롤의 영역을 물고 들어오는지 본다 — 각 슬라이더는 책임을 한 문장으로 말할 수 있어야 한다
- 컨트롤은 무엇을 조절할지뿐 아니라 무엇은 건드리지 않을지도 정한다
- 다음 할 일을 훑을 때 “지금 있는 것과 부딪히나”를 묻는다 — 만들고 나서 알면 구조를 다시 잡아야 한다