← 글 목록으로 돌아가기

React와 Remotion으로 만드는 장송의 프리렌 스타일 애니메이션 오프닝 영상 제작 가이드

코드 기반 비디오 렌더링 프레임워크 Remotion(github.com/remotion-dev/remotion)을 활용하여 인기 애니메이션 프리렌 감성의 패럴랙스, 마법 입자, 시퀀스 연출을 React로 구축하는 풀 가이드.

React와 Remotion으로 만드는 장송의 프리렌 스타일 애니메이션 오프닝 영상 제작 가이드

코드 기반 비디오 렌더링 Engine: Remotion

최근 프론트엔드 생태계에서 웹 기술(React, HTML5 Canvas, CSS Animation)을 활용해 정교한 비디오를 프로그래밍 방식으로 제작하는 패러다임이 큰 주목을 받고 있습니다. 대표적인 프레임워크가 바로 Remotion GitHub 저장소입니다.

Remotion은 타임라인 UI 중심의 에프터이펙트나 프리미어 프로 대신, 프레임 단위의 정확한 수식 계산과 컴포넌트 재사용성을 활용해 100% 코드로 고화질 MP4 영상을 렌더링할 수 있게 해줍니다.

이번 포스트에서는 인기 애니메이션 *장송의 프리렌(Frieren: Beyond Journey’s End)*의 몽환적이고 서정적인 오프닝 연출을 Remotion과 React 코드로 직접 제작하는 프로세스를 소개합니다.


🎨 프리렌 오프닝 연출의 3가지 핵심 요소

프리렌 감성의 오프닝 연출을 완성하기 위해서는 다음 3가지 비주얼 요소가 필수적입니다.

  1. 서정적인 패럴랙스(Parallax) 줌 및 패닝 효과: 카메라인 렌즈가 천천히 모션하며 이동하는 Ken Burns 효과
  2. 마법 입자(Magic Particle) 및 꽃잎 입자 연출: Canvas 기반 몽환적 입자 흐름
  3. 신비로운 타이포그래피(Typography) 등장: 글자 간격 확장, Glow 효과 및 텍스트 마스킹

🛠️ Remotion 환경 초기화

터미널에서 아래 프로젝트 창출 명령어로 Remotion 환경을 생성합니다.

npx create-video@latest frieren-op-demo
cd frieren-op-demo

설치가 완료되면 npm start 명령으로 브라우저 기반의 타임라인 Preview 플레이어를 열어실 수 있습니다.


🎬 코드 구성: 프리렌 오프닝 루트 컴포넌트 (Root.tsx)

비디오의 해상도(1920x1080), 프레임 레이트(60fps), 전체 프레임 수(180프레임 = 3초)를 등록합니다.

import { Composition } from 'remotion';
import { FrierenOpScene } from './FrierenOpScene';

export const RemotionRoot = () => {
  return (
    <Composition
      id="FrierenOpScene"
      component={FrierenOpScene}
      durationInFrames={180}
      fps={60}
      width={1920}
      height={1080}
      defaultProps={{
        title: 'FRIEREN',
        subtitle: 'Beyond Journey\'s End',
      }}
    />
  );
};

🌌 패럴랙스 배율과 마법 입자 씬 연출 (FrierenOpScene.tsx)

Remotion의 핵심은 useCurrentFrame()interpolate(), 그리고 spring() 훅을 활용한 프레임 정밀 계산입니다.

import {
  AbsoluteFill,
  interpolate,
  spring,
  useCurrentFrame,
  useVideoConfig,
} from 'remotion';
import React, { useMemo } from 'react';

export const FrierenOpScene: React.FC<{ title: string; subtitle: string }> = ({
  title,
  subtitle,
}) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();

  // 1. 카메라 서서히 확대 (Ken Burns 효과)
  const bgScale = interpolate(frame, [0, 180], [1.0, 1.15], {
    extrapolateRight: 'clamp',
  });

  // 2. 타이틀 페이드인 및 스프링 애니메이션
  const titleOpacity = interpolate(frame, [30, 90], [0, 1], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
  });

  const titleSpring = spring({
    frame: frame - 30,
    fps,
    config: { damping: 12 },
  });

  // 3. 자간 확장 효과 (Letter Spacing Animation)
  const letterSpacing = interpolate(frame, [30, 180], [10, 24], {
    extrapolateRight: 'clamp',
  });

  return (
    <AbsoluteFill style={{ backgroundColor: '#090d16', overflow: 'hidden' }}>
      {/* 배경 레이어 (신비로운 푸른빛 글래디언트 및 패럴랙스 확대) */}
      <AbsoluteFill
        style={{
          transform: `scale(${bgScale})`,
          background: 'radial-gradient(circle at 50% 40%, #1e3a5f 0%, #090d16 70%)',
          filter: 'contrast(105%) brightness(95%)',
        }}
      />

      {/* 마법 파티클 빛 레이어 */}
      <MagicGlowParticles frame={frame} />

      {/* 중앙 메인 타이틀 영역 */}
      <AbsoluteFill
        style={{
          justifyContent: 'center',
          alignItems: 'center',
          flexDirection: 'column',
          opacity: titleOpacity,
        }}
      >
        <h1
          style={{
            fontFamily: 'serif',
            fontSize: '110px',
            color: '#e2e8f0',
            letterSpacing: `${letterSpacing}px`,
            margin: 0,
            textShadow: '0 0 30px rgba(147, 197, 253, 0.6), 0 0 60px rgba(147, 197, 253, 0.3)',
            transform: `scale(${interpolate(titleSpring, [0, 1], [0.9, 1])})`,
          }}
        >
          {title}
        </h1>
        <p
          style={{
            fontFamily: 'sans-serif',
            fontSize: '24px',
            color: '#94a3b8',
            letterSpacing: '8px',
            marginTop: '16px',
            textTransform: 'uppercase',
          }}
        >
          {subtitle}
        </p>
      </AbsoluteFill>

      {/* 영화 같은 리터박스 (상하 시네마틱 흑색 바) */}
      <div
        style={{
          position: 'absolute',
          top: 0,
          left: 0,
          right: 0,
          height: '80px',
          backgroundColor: '#000000',
        }}
      />
      <div
        style={{
          position: 'absolute',
          bottom: 0,
          left: 0,
          right: 0,
          height: '80px',
          backgroundColor: '#000000',
        }}
      />
    </AbsoluteFill>
  );
};

// 마법 파티클 입자 렌더링 헬퍼 컴포넌트
const MagicGlowParticles: React.FC<{ frame: number }> = ({ frame }) => {
  const particles = useMemo(() => {
    return Array.from({ length: 40 }).map((_, i) => ({
      id: i,
      x: (i * 137.5) % 100, // 슈도 랜덤 좌표 분포
      baseY: (i * 93.1) % 100,
      size: 2 + (i % 5) * 2,
      speed: 0.1 + (i % 3) * 0.15,
      opacity: 0.3 + (i % 4) * 0.2,
    }));
  }, []);

  return (
    <AbsoluteFill>
      {particles.map((p) => {
        const currentY = (p.baseY - frame * p.speed + 100) % 100;
        const glowOpacity = interpolate(
          Math.sin(frame * 0.05 + p.id),
          [-1, 1],
          [p.opacity * 0.5, p.opacity]
        );

        return (
          <div
            key={p.id}
            style={{
              position: 'absolute',
              left: `${p.x}%`,
              top: `${currentY}%`,
              width: `${p.size}px`,
              height: `${p.size}px`,
              borderRadius: '50%',
              backgroundColor: p.id % 2 === 0 ? '#93c5fd' : '#fef08a',
              boxShadow: `0 0 ${p.size * 3}px ${p.id % 2 === 0 ? '#60a5fa' : '#fde047'}`,
              opacity: glowOpacity,
            }}
          />
        );
      })}
    </AbsoluteFill>
  );
};

⚡ 고화질 비디오 MP4 파일 렌더링

작성한 React 컴포넌트를 실제 비디오 파일로 추출하기 위해 Remotion CLI 명령을 실행합니다.

npx remotion render src/index.ts FrierenOpScene out/frieren_op.mp4

FFmpeg 기반으로 빠른 멀티스레드 렌더링이 진행되며, out/frieren_op.mp4 경로에 60fps의 매끄러운 몽환적 오프닝 영상이 생성됩니다.


💡 결론 및 추가 활용 팁

Remotion을 사용하면 애니메이션 영상뿐만 아니라 기술 소식 요약 숏폼, 깃허브 오픈소스 홍보 비디오, 코드 리뷰 스크린캐스트까지 React 코드만으로 자동화할 수 있습니다.

Three.js / React Three Fiber 라이브러리와 조합하면 마법 진 3D 렌더링이나 실시간 음원 Beat-sync 동기화까지 쉽게 확장이 가능합니다. 더 자세한 정보와 API 문서는 공식 저장소를 참고해 보세요.

NT

NewType Studio Editorial

기술과 디자인의 경계를 허무는 세련된 디지털 가치를 만듭니다.