TDS 인터랙션 컴포넌트 / 2026.01 ~ 2026.04
ProgressiveBlur에 대한 고찰
TL;DR
ProgressiveBlur는 위치에 따라 blur 강도가 점진적으로 달라지는 효과예요.
비슷해 보이는 blur를 만드는 것보다, Figma의 ProgressiveBlur가 실제로 어떤 효과인지 먼저 정의하는 일이 중요했어요. 시중의 많은 웹 구현은 backdrop-filter: blur(...)를 여러 레이어로 겹치고 linear-gradient로 블렌딩해 점진적인 blur처럼 보이게 만들어요.
저는 이 방식을 그대로 가져오기보다, 픽셀 위치에 따라 blur 값이 실제로 달라지는 효과로 ProgressiveBlur를 다시 정의했어요. 그래서 DOM 위에 레이어를 쌓는 방식이 아니라, shader에서 픽셀별 blur 값을 계산할 수 있는 WebGL canvas 기반 접근을 골랐어요.
문제 정의 Problem
Next Look & Feel 프로젝트의 일부로, Figma의 ProgressiveBlur 표현을 웹에서 구현해야 했어요. 처음에 중요했던 건 구현 방법을 바로 고르는 것이 아니라, 이 효과를 어떤 기준으로 ProgressiveBlur라고 볼 것인지 정의하는 일이었어요.
많은 웹 구현은 backdrop-filter 레이어를 여러 개 만들고 각 레이어를 gradient mask로 블렌딩해 점진적인 blur처럼 보이게 해요. 블렌딩 영역을 넓게 주면 꽤 자연스러워 보일 수 있어요.
하지만 Figma의 실제 ProgressiveBlur와 비교하면 차이가 드러났어요. 레이어를 섞어 만든 효과는 여러 blur 결과를 자연스럽게 블렌딩하는 방식이지, 픽셀마다 blur radius가 실제로 연속적으로 달라지는 구조는 아니었어요.
접근 방식 Approach
ProgressiveBlur를 레이어 합성 문제가 아니라 픽셀별 blur 값을 계산하는 문제로 봤어요. 여러 blur 레이어를 gradient mask로 섞는 방식은 구현은 쉽지만, 픽셀별 blur 값이 연속적으로 변하는 구조는 아니었어요.
그래서 shader에서 위치에 따라 blur 값을 계산하는 WebGL canvas 기반 접근을 검토했어요. WebGL은 DOM에 직접 효과를 입히는 방식이 아니라 canvas 안에서 texture를 렌더링하는 방식이에요. 그래서 이미지나 비디오처럼 texture로 올릴 수 있는 에셋이 필요했어요.
이번 대상은 마침 이미지나 비디오처럼 texture로 올릴 수 있는 에셋 기반 표현이었어요. 덕분에 WebGL canvas와 shader를 활용할 수 있는 조건이 갖춰져 있었어요.
핵심 결정 Decision
backdrop-filter 레이어 방식 대신 WebGL canvas 기반 구현을 선택했어요.
CSS backdrop-filter 방식은 DOM 위에 바로 적용하기 쉽고 구현도 상대적으로 단순해요. 하지만 정확한 ProgressiveBlur라기보다는 여러 blur 레이어를 gradient로 섞어 비슷하게 보이게 만드는 방식에 가까웠어요. 게다가 backdrop-filter는 이미 비싼 스타일 연산이라, 더 자연스러운 결과를 내려고 레이어 수를 늘리면 성능 비용도 같이 커질 수 있었어요.
WebGL 방식은 canvas와 texture로 올릴 수 있는 에셋이 필요하고 구현 난도도 훨씬 높아요. 대신 픽셀별로 blur 값을 계산할 수 있기 때문에, Figma의 ProgressiveBlur에 더 가까운 연속적인 blur 변화를 만들 수 있었어요.
해결 결과 Result
shader가 픽셀별 blur 값을 직접 계산하도록 만들면서, 레이어를 섞어 흉내 내던 방식과 달리 blur radius가 위치를 따라 연속적으로 변하는 결과를 얻었어요.
ProgressiveBlur는 WebGL canvas와 shader 기반의 interaction 컴포넌트로 자리 잡았고, 이후 실제 알고리즘 선택과 framebuffer 파이프라인 구현으로 이어졌어요.
배운 점 Learning
이 작업을 하면서 canvas와 WebGL을 처음 본격적으로 다뤄봤어요. WebGL은 DOM에 직접 효과를 입히는 방식이 아니라 canvas 안에서 에셋을 texture로 올려 렌더링하는 방식이라는 걸 체감했어요.
ProgressiveBlur 같은 효과를 웹에서 구현하려면, 이걸 DOM에 적용할지 에셋 기반 렌더링으로 다룰지부터 갈라야 했어요. 효과를 어떻게 정의하느냐가 곧 렌더링 패러다임 선택으로 이어질 수 있다는 감각이 이번 작업에서 남았어요.