코드와 함께 춤을 추는 실험적인 모션

– ArtXTech

GSAP에서 WebGL과 터치 디자이너를 거쳐 Remotion으로 Canvas API렌더링까지, 크리에이티브 코딩 연대기

시작: GSAP와 배너 광고의 시대

처음으로 웹 애니메이션의 세계에 본격적으로 발을 들인 것은 한 에이전시에서 GSAP(GreenSock Animation Platform)를 사용하여 배너 광고를 제작하면서부터다. 당시 작업은 포토샵으로 제작된 스토리보드와 이미지 에셋을 받아, 이를 스프라이트 시트(Sprite Sheet)로 만들고 고정된 크기의 배너 창 안에서 타임라인 기반의 애니메이션을 구현하는 것이었다.

// 예시: GSAP를 사용한 기본적인 배너 애니메이션 코드
import { gsap } from "gsap";

<img src="/digitalgarden/assets/images/CV-ux">// DOM 요소 선택
const logo = document.querySelector('.logo');
const title = document.querySelector('.title');
const ctaButton = document.querySelector('.cta-button');

// 타임라인 생성
const tl = gsap.timeline({ repeat: -1, repeatDelay: 2 });

tl.from(logo, { duration: 0.5, opacity: 0, x: -50, ease: "power2.out" })
  .from(title, { duration: 0.7, opacity: 0, y: 30, ease: "back.out(1.7)" }, "-=0.2")
  .from(ctaButton, { duration: 0.5, scale: 0, ease: "elastic.out(1, 0.5)" });

// 이 코드는 로고, 타이틀, CTA 버튼이 순차적으로 나타나는 간단한 애니메이션을 구현

그때는 Flash나 전문 애니메이션 툴이 여전히 강세였지만, 의도적으로 HTML5와 CSS3, 그리고 JavaScript(주로 jQuery와 GSAP)를 고수했다. 가장 큰 이유는 ‘파일 용량’ 때문이다. 미디어 에이전시를 통해 광고를 집행할 때, 배너의 노출 트래픽 비용은 렌더링되어 전송되는 파일의 크기에 정비례하여 책정된다. 파일 용량이 클수록 광고 송출 비용은 기하급수적으로 증가한다.

이러한 제약 속에서 이미지 압축 기술, 자연스러운 애니메이션을 위한 최적화, 그리고 프레임 단위의 정교한 애니메이션을 구성하는 감각을 집중적으로 연마할 수 있었다. 제한된 환경에서 꼼수를 쓰는 잔머리는 참 잘도 늘어갔다.

예전에 만들었던 GSAP 배너들

오로지 스프라이트킷, GSAP, CSS3, HTML5로만 구성된 애니메이션들이다. 그노무 50kb 이하 클릭/노출수당 트래픽 비용 제한 때문에…ㅠ

공백기 동안 잊어먹은 웹 애니메이션 구현 감각

프리랜서로 여러 에이전시에서 웹 애니메이션 프로젝트를 수행하다, 마케팅 기술을 전문으로 다루는 회사로 이직하면서 약 5년간 크리에이티브 코딩과는 잠시 멀어졌다. 전 회사에서 얼추 4년 반을 Marketing Tech 및 CRO Data Analytics와 협업하는 에이전시에서 UX Technologist로도 일하면서 이 프로젝트 저 프로젝트 다 넘나들며 다양한 경험을 하였지만 그 어느것도 내가 그간 해왔던 크리에이티브한 비쥬얼 구현과는 거리가 멀어서 나의 가장 큰 주특기이던 코드로 렌더링 최적화를 이루며 애니메이션과 모션을 구현하는 테크니컬 디자인의 일을 하는 일은 점점 멀어졌다.

그러다 여러 이유로 내 커리어의 방향에 대해 다시 스스로에게 물음을 던지며 설상가상 여러모로 갑작스레 닥친 크고 작은 일들로 결국 스트레스가 극에 달해 번아웃이 신체화로 도져 건강이 심하게 악화되었다. 결국 나는 2024년, 대학원 복학을 계기로 잠시 업계를 나가고 퇴사를 한 뒤 그간 잠시 멈춰왔던 데이터사이언스 대학원 이수를 다시 시작했다. 24년 하반기에 접어들면서 문득 제 크리에이티브 코딩 및 UX 디자인 시스템 빌딩 스킬셋이 낡아버렸다는 위기감을 느꼈다. 그래서 다시 GSAP, PIXI.js, Three.js를 집어 들었다. 가히 5년 만이었다.

세상은 너무나 많이 변해있었다. 주로 사용하던 Gulp, Grunt, Webpack 같은 빌드 툴은 Vite로 대세가 넘어간 듯 보였다. HTML에 CDN 링크를 걸어 개발하던 시절이 단순해서 좋았다는 생각마저 들었다. Vite가 어떤 파이프라인으로 에셋과 코드를 처리하는지 감을 잡는 데만 상당한 시간을 쏟아야 했다.

그런데 문득 웃기단 생각이 든다. 지난 4년간 지난 회사에서 일할 때도 매번 쏟아져 나오는 신기술들을 익히느라 바쁘게 보냈던 기억밖에 없단 말이다. 근데 그 4년 간 매번 트렌드 기술을 따라잡고 새 자격증들을 갱신하느라 바빠왔던 세월들은 나에게 아무런 재산이 되어주지 못했다. 내가 만드는 코드들은 당장 클라이언트의 독촉과 Best Practice 따윈 관심없는 타 직업군 동료들의 닥달을 달래기 위해 얼기설기 매번 마감을 치기 바쁘다보니 깔끔한 가독성과 일관적인 구조의 디자인이 강점이던 나의 코드 감각은 되려 녹이 슬어갔다. 지난 회사에서 일하는 기간 동안 정말 매번 회사와 프로젝트에 전념해 일한 기억밖에 없건만 이렇다하게 레벨업한 느낌이라곤 전혀 없었다는게 너무나 아이러니했다.

그런데 하등 이해가 아예 안 가는 것도 아니었다. 비지니스에서 요구하는 학습이란 새로 나온 플랫폼을 이용하기 위한 자격증들이었다. 이런 플랫폼 연관 자격증들은 매번 새 프로덕트나 플랫폼의 아키텍처가 변경될 때마다 바뀌었고 내가 알고 있던 것들은 다 폐기물이나 거진 다름없다. 이건 CSS나 타입스크립트가 버전업을 하며 그에 맞춰 다른 Abstract 레이어 및 생태계에 대한 이해를 업데이트하는 것관 차원이 다른 문제였다. 코어가 없는 지식학습을 4년 반 동안 지속해야했고 이렇게 매번 프로젝트를 수주받기 위한 학습 및 자격요건은 5-6개월이 지나면 아무짝에 쓸모가 없어진다. 가장 최악인 것은 이것은 내가 원한 것이 아니라 업계에서 경제권, 그러니까 직장을 계속 다니려면 어쩔 수 없이 해야하는 것들이라는 것이다. 번아웃이 안 오는 게 이상하지.

과거에는 HTML5, CSS3, jQuery, 순수 JS를 조합해 깔끔하게 구현했지만, 이제는 모든 것을 React 컴포넌트 아키텍처 위에서 처리하는 것이 표준이 되어 있다. 지난 4년간 React를 사용해왔음에도, UI 스타일 가이드 빌드와 웹 애니메이션 구현을 위한 React의 사용법은 또 다른 차원의 어려움으로 다가왔다. 웹앱에서 리액트를 구현하는 건 사실 어렵지 않았다. 디자인 시스템 구현도 그렇게 까다로울 정도는 아니다. 하지만 프레임마다 기동하는 애니메이션을 아무런 랙 없이 구현하는 것은 다른 문제다. 리액트 같이 자체적으로 요하는 암묵룰이 강한 생태계에선 비쥬얼을 웹에서 렌더링하는 데 필요한 디버깅의 난이도가 훨씬 높아진다. 단순히 데이터나 타입패싱 체크로는 애니메이션 디버깅을 할 수 없다. 반할 이상은 아무런 콘솔로그 에러를 벹지 않기 때문이다.

이번엔 React와 TypeScript 형식에 맞춰 다시 도전하는 GSAP와 WebGL

// React와 GSAP를 함께 사용하기 위한 useGSAP 훅 예시
import { useGSAP } from '@gsap/react';
import { useRef } from 'react';

function MyComponent() {
  const container = useRef();

  useGSAP(() => {
    // useGSAP 훅을 사용하면 컴포넌트 라이프사이클에 맞춰
    // GSAP 애니메이션을 안전하게 생성하고 정리할 수 있습니다.
    gsap.to(".box", { rotation: "+=360", duration: 2 });
  }, { scope: container }); // scope를 지정하여 해당 DOM 내에서만 셀렉터가 동작하도록 제한

  return (
    <div ref={container}>
      <div className="box">Hello</div>
    </div>
  );
}

애니메이션 글리치가 발생했을 때, 순수 JavaScript 환경에서의 디버깅도 골치 아픈데 React와 Vite 위에서는 문제의 원인이 정확히 어디에 있는지 파악하기가 훨씬 더 힘들어졌다. 여러 라이브러리가 복잡하게 얽혀있기 때문에 그렇다. 프론트엔드 개발자들이여, 우리는 왜 매번 이런 고된 길을 자처하는가…눈물이 핑 돈다 돌아…아놔.

하지만 그렇게 하나하나 부딪히고 해결해가며 잊었던 감각을 되살리기 시작했다. 생전 건드려보지 않았던 쉐이더(Shader)의 세계에도 발을 들였다.


## 예상치 못한 연계성: Science X Tech X Engineering X Art X Math

업계에서는 목적과 의미를 알 수 없는 작업을 반복하며 소진되는 일이 잦았다. 하지만 이제는 온전히 만들고 싶은 것에 대한 명확한 청사진을 그리고, 그것을 실현하기 위해 코드를 짜는 즐거움을 되찾았다.

다시 그래픽스 아트를 코딩으로 구현하며 이것저것 시험해보는 감을 잡기 시작하니 더욱 다양한 효과를 시도했다.

그러던 중, 대학원 과제로 Python을 이용해 이미지 분석 작업을 하다가 ’코드로 비주얼 특수 효과를 구현할 수 있지 않을까?’라는 아이디어가 떠올랐다. 데이터 사이언스 공부가 현업 복귀에 쓸모없을지도 모른다는 불안감을 ‘덕질을 위한 근본적인 학업’으로 적극적으로 현실도피를 하고 있었다. 덕분에 지루했던 공부를 잘 엉덩짝 붙이고 버티게 해줘 과제 중심 수업에선 대부분 A를 받았다.

어린 시절 닌텐도 게임보이나 DOS 게임에 대한 향수로, 제가 그린 그림을 아스키 아트로 변환하는 작업을 하기도 했다.

나중에 알게 된 사실이지만, 이미 Github에 이런 식으로 그림을 ASCII로 변환해주는 코드는 참 널렸던 걸 발견하고 좀 허무해졌지만, 뭐 모든 걸 다 경험이라 여겨야지.

graph TD
    A[이미지 입력] --> B{이미지 처리};
    B --> C[그레이스케일 변환];
    C --> D[리사이징];
    D --> E{픽셀 밝기 분석};
    E --> F[아스키 문자에 매핑];
    F --> G[아스키 아트 출력];

창작의 불씨를 지핀 사건들 - 분노의 키네틱그라피

12월 초에 들어와 나의 모국에서 ‘계엄’이라는 충격적인 사건이 터졌다. 한국에 돼지 강점기를 도입한 것도 모잘라 계엄이라니. 멀쩡한 나라에서 이게 무슨 일인가. 분노가 치밀어 올랐지만, 해외에 있는 내가 할 수 있는 일은 많지 않았다. 이 울분을 풀기 위해 키네틱 타이포그래피 애니메이션을 만들었다. 복잡한 툴 대신, 가장 빠르고 미니멀하게 제 감정을 표현할 수 있는 React와 CSS3를 택했다.

Remotion과의 만남, 그리고 새로운 워크플로우 정립

분노는 쉽게 가라앉지 않았다. 음향 작업, 어려운 대학원 수업 등 여러 장벽에 부딪히며 좌절하던 중, Remotion이라는 프레임워크를 발견했다. React를 기반으로 프로그래밍 방식으로 영상을 만드는 모션 그래픽 라이브러리였다.

Remotion 역시 Adobe After Effects나 DaVinci Resolve처럼 직관적인 GUI 툴은 아니었지만, React 컴포넌트를 비디오로 출력할 수 있다는 점은 새로운 가능성을 열어주었다. 특히 계엄 사태 이후 경제 지표들을 시각화하며 만들었던 차트 컴포넌트들을 Remotion으로 불러와 영상으로 만들 수 있겠다는 생각이 들었다.

이 시기를 거치며 나만의 프로토타이핑 워크플로우를 정립했다.

graph TD
    A[1 아이디어 구상] --> B(2 피그마: 이미지/디자인);
    B --> C(3 필모라: 간단한 모션 아이디어 스케치);
    C --> D(4 Jitter/Cavalry: 웹 기반 툴로 프로토타입 구현);
    D --> E(5 Remotion: 코드로 최종 모션 구현);

Jitter와 같은 툴은 간단한 애니메이션 프로토타입을 빠르고 저렴하게 만들기에 아주 유용했다. 이 워크플로우를 통해 아이디어를 구체화하고 기술적으로 구현하는 과정을 체계화할 수 있었다.

Remotion을 쓰기 시작하며 얻게된 재미난 점은 내가 Web App을 위해 개발했던 UI 컴포넌트 중 일부를 영상 모션을 위해 차용할 가능성이 열린 것이다.

가령 예를 들면 내가 4월달에 개발한 타임라인 Data Visualisation 차트 보고서 페이지를 보자.

이 타임라인 웹페이지에서 쓰인 차트들을 일부 골라 Remotion으로 살짝의 변형을 거쳐(아무래도 기동 프레임워크 로직이 살짝 다르다보니) import된 모습이다.

그리고 이건 2025년 초에 스케치로 작성했던 키네틱 작업 중 일부를 Remotion 기반의 GSAP 코드베이스에 옮기는 장면이다. 이런 식으로 UI로 초반에 구성했던 스케치 컴포넌트를 살짝 변환만 거치면 모션 디자인 컴포넌트로도 쓸 수 있다. 그 반대로 모션 디자인을 위해 구현했던 엘레먼트의 일부를 다른 웹사이트 UI로 변환해 쓸 수도 있는 것이다. 이런 프레젠테이션 레이어의 경계를 넘나드는 자율성이 Remotion을 통해 작업하는 이점이라 볼 수 있다.

본격적으로 진행되는 기술과 비쥬얼 아트의 융합

쉐이더를 본격적으로 Remotion에 연동하여 glitchbreakneo-y2kvaporwave 같은 서브컬처 미학을 실험했다. Acid/Antiperfect 디자인 정체성을 살려 그리드를 무시하고, TouchDesigner, Figma, Remotion 등 다양한 툴에서 Dithering 알고리즘을 시험했다.

TouchDesigner에서 프로토타이핑한 displacementchromatic aberration(색수차) 효과를 GLSL 코드로 변환했다. 이 쉐이더를 GSAP로 타이밍을 조절하여 Remotion에서 횡스크롤 애니메이션을 구현하는 데 성공했다.

터치디자이너는 상당히 대단한 프로그램이다. 커뮤니티도 활발하고 내가 블렌더와 Shader에 대한 감각이 있다면 GLSL을 일부 작성해서 효과로 불러들여 쓸 수도 있다. 터치 디자이너는 이펙트가 들어간 단시간 짧은 영상을 만들거나 반복되는 루프물을 구현해 VJ로 빔프로젝트를 통해 비쥬얼과 퍼포먼스를 만드는 데 이점이 있는 것 같다.

다만 나의 작업은 어느 정도 기승전결이 담긴 시각적 암시가 들어간 메시지가 많기 때문에 터치디자이너로만 작업을 할 수는 없었다. 그래도 터치디자이너는 프로토타입으로 구상하는 이펙트 이미지를 담은 영상을 만들거나 다채로운 감각적인 비쥬얼을 만들기엔 아주 최상인 툴이라서 영상 편집할 때 쓰일 Footage를 만들기엔 가장 최적이라 생각한다.

그래서 Touch Designer로 이니셜 컨텐츠를 만들면 그걸 Remotion으로 Importing해서 타이핑 컴포넌트를 입히는 방식을 채용했다. Jennie의 Like Jennie에 맞춰 추던 댄스커버 영상을 터치 디자이너에서 이것저것 깨작거리며 만든 이미지를 반영한 영상을 리모션으로 불러들여 쉐이더를 입혔다. 그 다음 Top 레이어에 타이포그래피를 얹어서 타이핑 이펙트를 얹어보았다.

그리고 이 타이핑 작업은 나중에 TTS 제미나이와 협업해 짧은 토크쇼 팟캐를 만드는 실험적인 에피소드 제작의 기반이 된다.

// 간단한 색수차 효과 GLSL 프래그먼트 쉐이더 예시
#version 300 es
precision mediump float;

uniform sampler2D u_texture;
uniform float u_displacement;
in vec2 v_texCoord;
out vec4 outColor;

void main() {
  // 텍스처의 R, G, B 채널을 약간씩 다른 좌표에서 샘플링
  float r = texture(u_texture, v_texCoord - vec2(u_displacement, 0.0)).r;
  float g = texture(u_texture, v_texCoord).g;
  float b = texture(u_texture, v_texCoord + vec2(u_displacement, 0.0)).b;

  outColor = vec4(r, g, b, 1.0);
}

이윽고 6-8월엔 대학원에서 계절 학기를 수강하며 일러스트에 ditheringhalftoneglass fx 등 다양한 효과를 적용하는 실험을 계속했다. Gemini TTS로 음성을 받아 팟캐스트를 만들고, 코드로 YouTube 팟캐스트를 출력하는 시도도 했다. 이 시기, 수학 증명 과제가 쉐이더 구현 원리를 이해하는 데 도움이 되는 전화위복의 순간도 있었다. FFT, 아이젠벡터, PCA 같은 통계 모델이 예술적 표현에 유용하게 쓰일 수 있다는 것을 깨달았다.

아이러니하게도 필드에서 일하다가 성장의 한계를 깨닫고 정처를 해매다 들어간 대학원에서 배운 수학지식들이 Generative Art 및 VFX GLSL Shader를 구성하는데 많은 도움을 주는 경험을 한다.

새삼스럽게 어릴 때부터 내가 항상 명시하던 이 철학을 다시 상기한다. 과학과 수학과 엔지니어링과 기술과 예술은 전혀 다른 분야가 아니라는 것을. 이런 말을 하면 아무도 안 믿어주지만 말이다. 하지만 어떠한가. 나의 작업들이 그 자체로 이걸 증명하는데.

계절학기가 끝나고 그동안 빌드업한 기술과 미감을 총동원해 리믹스 뮤직비디오를 제작했다. 80년대 사이키델릭, 90년대 lo-fi, 2020년대 하이퍼팝, y2k 글리치코어 등 제가 사랑했던 서브컬처 미장센을 모두 담았다.

이미지와 추구하는 미학의 방향을 정하고 나니 뭔가 후련해졌다. 이제 이 기조로 계속 틈틈히 비쥬얼 작업을 하는 수밖에. 저 영상 비쥬얼 작업은 Shader와 Remotion을 많이 이용했지만 영상의 모든 부분을 다 이 두 가지로 해결하는 건 효율성에서 문제가 있었다. 어떤 작업은 그냥 Video Editor를 쓰는게 훨씬 편할 때가 있고 어떤 작업은 WebGL과 Remotion을 연동하는 경우 중첩으로 쉐이더를 프로세싱할 때 캔버스 API에 여러 개의 쉐이더를 얹기 힘들어 그냥 쉐이더를 직접 코딩해서 Video Editor의 FX플러그인으로 만든 다음 이걸 Import하는게 훨씬 나은 경우도 잦았다. 그래도 코드와 쉐이더를 내가 직접 사용해 부분 작업이라도 활용을 할 수 있다는 것은 그냥 모든 걸 쌩으로 Motion Graphics 툴로 차력쇼하는 것보단 훨씬 다양한 확장성을 가져왔다.

김완선 님의 ‘Yellow’ 뮤직비디오 리믹스 작업을 하며, Remotion의 Alpha Channel 기능을 활용해 영상의 특정 부분만 따내 마스킹하는 데 성공했다.

// Remotion에서 알파 채널 비디오를 사용하는 예시
import { OffthreadVideo, staticFile } from 'remotion';

export const MyComposition = () => {
  // 알파 채널이 포함된 WebM 비디오 파일
  const videoWithAlpha = staticFile('/videos/dancing-figure.webm');

  return (
    <div style={{ backgroundColor: 'blue' }}>
      {/* 배경 위에 알파 채널 비디오를 렌더링 */}
      <OffthreadVideo src={videoWithAlpha} />
    </div>
  );
};

이 고된 작업을 하며 ‘차라리 DaVinci Resolve를 배우는 게 낫지 않았을까?’ 하는 생각이 들기도 했지만, HTML5 Canvas와 웹 기술만으로 여기까지 해냈다는 사실에 큰 성취감이 든다(사실 여러 에디터 툴 익히는 시간이나 걍 코드 잡고 디버깅하느라 머리털 뽑는 고통이나 도찐개찐이다)

마치며 - 웹과 영상의 경계를 허물다

지난 1년간의 여정은 단순한 웹 애니메이션 기술 탐구를 넘어, 웹 엔진을 통해 비디오를 렌더링하는 과정에 대한 깊은 이해를 가져다주었다. 이 과정에서 축적된 컴포넌트 기반의 디자인 시스템과 코드들은 이제 모션 그래픽 영상 제작뿐만 아니라, 미감을 극적으로 강조한 인터랙티브 웹페이지를 제작할 때도 강력한 무기가 되었다.

반대로, 웹 UI를 위해 만들었던 컴포넌트를 영상물로 변환하는 것(vice-versa)도 가능해졌다. 실제로 웹페이지의 Hero 배너 애니메이션 컴포넌트를 가져와 영상 디자인으로 전환한 작업도 많았다.

이제 나에게 웹과 영상의 경계는 의미가 없다. 코드는 캔버스고, 브라우저는 새로운 형태의 편집 툴. 앞으로 이 두 세계를 넘나들며 어떤 새로운 창작물을 만들어낼 수 있을지 매일 이런 저런 아이디어를 내고 VSC에디터를 노려보며 고민해본다.