- Aras는 Blender에 Video Sequence Editor(VSE) 가 있다는 사실도 몰랐지만, Blender HQ 방문 뒤 약 두 달간 파트타임으로 Blender 4.1용 성능·품질 개선을 기여함
- 가장 눈에 띄는 변화는 타임라인 반응성으로, 약 3000개 strip이 보이는 Sprite Fright 프로젝트에서 스크롤·패닝 UI가 약 15fps에서 60fps 이상으로 개선됨
- ffmpeg 기반 RGB↔YUV 변환, Audaspace 오디오 리샘플링, 이미지 변환·필터링, VSE 효과 처리에 멀티스레딩·SIMD·수학 단순화가 적용됨
- 세 개의 Blender Studio 데이터셋에서 작성자 PC 기준 VSE 영화 최종 렌더 시간이 약 2배 빨라졌고, Sprite Fright 렌더링은 거의 13분에서 7분으로 줄어듦
- 총 37개 pull request가 리뷰·병합됐으며, Blender 4.1에는 현재 변경이 들어가고 이후 VSE 작업은 Blender 4.2부터 이어질 예정임
Blender VSE에 기여하게 된 경위
- Aras는 Unity의 Unite 2023 참석차 Amsterdam에 갔다가 남는 시간에 Blender HQ를 방문함
- 그곳에서 Francesco와 Sergey가 VSE 기여 의사를 물었고, 이후 Blender의 Video Sequence Editor를 건드리기 시작함
- 영상 편집, 타임라인, 시퀀서, 컬러 그레이딩, ffmpeg, 오디오 믹싱을 잘 모르는 상태였지만, 논쟁 여지가 적은 성능 최적화부터 진행함
- 약 두 달의 파트타임 작업 끝에 Blender 4.1에 들어갈 개선 묶음이 생김
- Blender 4.1은 베타가 되었고, 일반 daily builds에서 받을 수 있음
타임라인 그리기와 UI 반응성
- VSE 타임라인은 화면 하단 영역이며, Sprite Fright edit 전체 프로젝트를 줌아웃하면 약 3000개 strip이 한 번에 보임
- 기존에는 이 타임라인에서 스크롤·패닝만 해도 UI 갱신이 약 15fps 수준에 머물렀음
- 변경 뒤에는 60fps 이상으로 동작함
- 관련 PR: #115311
- 병목은 그래픽 API draw call을 삼각형 두 개 단위로 제출하는 구조였고, Superluminal 프로파일러에서 대부분 시간이 “quad 하나 그리기 시작”과 “quad 하나 그리기 종료” 함수 안에서 쓰였음
- 이 과정에서 오디오 waveform 표시의 이상 동작도 고치고 UI를 다듬었으며, waveform 표시는 기본값으로 켜짐
- 관련 이슈: #115274
스코프 표시 품질과 속도 개선
- VSE는 이미지 히스토그램, waveform, vectorscope 같은 일반적인 스코프(scope) 표시 옵션을 제공함
- 히스토그램은 픽셀화된 이미지와 매우 강한 채도로 그려졌지만, 이제 더 부드러운 polygon, grid, 낮은 채도로 표시됨
- 관련 PR: #116798
- Waveform의 parade 옵션은 너무 빨리 포화되는 문제가 있었고, 멀티스레딩 적용 후 15배 빨라짐
- 관련 PR: #115579
- Vectorscope의 외곽 색상 육각형은 픽셀화가 심했으며, 이미지 에디터 vectorscope의 갱신된 design을 복사해 적용함
- 관련 PR: #117738
- “과노출 영역 표시”에 해당하는 zebra stripes 옵션도 2~3배 빨라짐
- 관련 PR: #115622
- 모든 스코프와 이미지 에디터 스코프는 언젠가 GPU compute shader로 처리되어야 한다는 생각도 덧붙임
ffmpeg RGB↔YUV 변환 최적화
- Blender는 오디오·비디오 읽기와 쓰기에 주로 ffmpeg 라이브러리를 사용함
- Blender 내부에서는 ffmpeg 명령줄 도구가 아니라 libavcodec 같은 코드 라이브러리를 쓰며,
libswscale은 영화 프레임의 RGB↔YUV 변환을 담당함 libswscale은 멀티스레드 변환을 지원하지만, 단순히sws_getContext()와sws_scale()을 쓰면 완전히 단일 스레드로 동작함- 멀티스레딩을 쓰려면 초기화 시점에
"threads"파라미터를 설정해야 하므로sws_alloc_context(),av_opt_set_int(),sws_init_context()를 직접 사용해야 함 - 또한
sws_scale()은 내부적으로 멀티스레딩을 하지 않기 때문에sws_scale_frame()을 써야 했고, 이 과정에서AVFrame생성 방식의 문제도 드러남 - 결과적으로 영화 파일 쓰기 시 RGB→YUV 변환이 상당히 빨라짐
- 관련 PR: #116008
- 영화 파일 읽기에서도 멀티스레드 YUV→RGB 변환을 사용하고, vertical flip을 같은 작업에 합침
- 관련 PR: #116309
오디오 리샘플링
- VSE에서 영상을 렌더링할 때 “비디오 또는 오디오 프레임을 생성”하는 시간의 거의 절반이 Blender가 사용하는 오디오 라이브러리 Audaspace 안에서 쓰이는 상황이 확인됨
- 병목은 오디오 인코딩이 아니라 인코딩 전 믹싱이었고, 대부분은 48kHz 영화 안에 44.1kHz 같은 오디오 strip이 섞일 때 발생하는 리샘플링에 쓰임
- Audaspace에는 두 가지 리샘플링 모드가 있었음
- Blender 내부 재생: 샘플 사이를 선형 보간하는 Linear resampler
- 영화 렌더링: Julius O Smith’s algorithm 기반 리샘플러
- 리샘플러 품질은 단일 주파수가 증가하는 합성음을 리샘플링한 뒤 spectrogram을 보는 방식으로 비교함
- 목표는 Audacity의 “best” 설정처럼 추가 주파수가 최대한 적은 결과임
- Audaspace의 preview 리샘플링은 계산은 빠르지만 많은 추가 주파수를 만들었고, rendering 리샘플링은 spectrogram 품질이 좋았음
- 새 medium 리샘플링 품질을 Audaspace에 추가했고, 작성자가 보기에는 거의 같은 결과를 내면서 계산은 약 3배 빨라짐
- Blender는 렌더링 시 이 medium 설정을 사용하게 됨
- Windows Ryzen 5950X PC에서 Sprite Fright 2000프레임 렌더링이 92초에서 73초로 줄어듦
- 관련 PR: #116059
이미지 변환과 필터링
- VSE에서 이미지, 영화, 텍스트, scene 등 시각 결과를 만드는 strip은 위치, 회전, 스케일, crop을 적용할 수 있음
- 이런 변환은 strip이 만든 이미지를 새 이미지로 변환하는 방식이며, 기존에도 CPU에서 멀티스레드로 처리됐음
- GPU가 아니라 CPU에서 처리되는 이유는 아직 GPU 구현이 없고, GPU가 없는 render farm에서 렌더링하려는 사용 사례를 위해 CPU fallback이 현재는 필요하기 때문임
-
Half-pixel 오차 수정
- 기존 코드에는 여러 off by half a pixel 오류가 있었고, 많은 경우 상쇄되거나 보이지 않았지만 특정 상황에서는 드러남
- 작은 이미지를 16배로 확대할 때 Bilinear 필터가 이미지를 원본 픽셀의 절반만큼 밀었고, 배경색인 magenta가 끼어드는 현상도 있었음
- 반대로 이미지를 정확히 2배 축소할 때 Bilinear 필터가 필터링을 전혀 하지 않는 문제도 발생함
- Bilinear와 다른 필터의 “off by something” 오류가 수정됨
- 관련 PR: #116628
-
Bilinear 투명 테두리 처리
- Blender 4.0 이전 VSE에는
Nearest,Bilinear,Subsampled3x3세 가지 필터 옵션이 있었고, 이 중 Bilinear만 결과 이미지 주변에 원본 texel 절반 너비의 투명도를 추가했음 - 이 동작은 미디어를 확대할 때 눈에 띄었고, 왜 이런 차이가 생겼는지는 기억하는 사람이 없었음
- VSE의 Bilinear 필터 코드에서 “투명도로 블렌딩”하는 동작을 제거함
- 다만 회전만 적용할 때는 기존 투명도 처리 덕분에 edge에 일종의 안티앨리어싱이 생겼기 때문에, 대신 destination 이미지의 edge pixel에 transparency anti-aliasing을 적용함
- 관련 PR: #117717
- Blender 4.0 이전 VSE에는
-
Cubic, Box, Auto 필터
- 일반 VSE strip transform에는 cubic 필터 옵션이 없었고, 특수 Transform Effect strip에만 존재했음
- Blender에서 “Bicubic”은 실제로 Cubic B-Spline 필터를 뜻하며, Mitchell-Netravali filter의 B=1, C=0 계수와 같음
- 작성자는 이를 “ringing은 없지만 blur가 많은” 선택으로 정리함
- VSE에는 두 종류의 cubic filtering 옵션이 들어감
- 관련 PR: #117100, #117517
- Blender 3.5의 “Subsampled 3x3” 필터는 실제로 3x3 크기로 하드코딩된 box filter였고, 3x3이 아닌 비율로 축소하면 무너지기 시작했음
- 이 필터는 고정 3x3이 아닌 조정된 Box filter로 바뀜
- 관련 PR: #117584
- 사용자가 선택해야 할 필터가 많아져서 VSE strip의 기본값으로 Auto filter option이 추가됨
- 관련 PR: #117853
- 스케일·회전이 없으면
Nearest - 2배 초과 확대면
Cubic Mitchell - 2배 초과 축소면
Box - 그 외에는
Bilinear
-
필터링 성능 개선
- 이미지 필터링 과정도 더 빨라짐
- 내부 루프에서 virtual function 제거, Bilinear 필터링에 SIMD 일부 적용: #115653
- Cubic 필터링 단순화와 SIMD 추가: #117100
- Box 필터의 수학 단순화: #117125
- 화면 전체를 덮는 solid image 아래 항목을 건너뛰는 최적화가 scale이 있을 때 동작하지 않던 문제 수정: #117786
- 작성자 PC에서 3840x2160 프로젝트에 1920x1080 이미지 하나를 2배 확대하고 Bilinear 필터링을 쓸 때, sequencer preview 전체 그리기가 36.8ms에서 15.9ms로 줄어듦
- 업샘플 필터 비교용 인터랙티브 페이지도 제공함: aras-p.info/img/misc/upsample_filter_comp_2024
VSE 효과 최적화
- Blender Studio의 실제 영화 데이터셋은 effect를 많이 쓰지 않았지만, 코드에서 보이는 부분을 중심으로 VSE effect도 최적화함
- 대부분의 변화는 멀티스레딩 적용임
최종 렌더 시간 변화
- Blender Studio에서 받은 세 개의 데이터셋 기준, 작성자 PC에서 VSE 영화 최종 렌더 시간이 약 2배 빨라짐
- Sprite Fright edit 렌더링은 거의 13분에서 7분으로 줄어듦
- 작성자는 추가 속도 향상을 바라고 있으며, “2배 속도 향상을 세 번 더 하면 꽤 좋다”는 식으로 표현함
작업 방식과 다음 단계
- 사용자에게 보이는 변경 외에도 테스트 추가, 리팩터링, 정리 작업을 위한 pull request가 있었고, 총 37개 pull request가 완료·리뷰·병합됨
- 작성자는 이 정도 작업을 “실제 직장”에서는 하기 어려웠을 것 같다고 평가함
- Unity에서 2015~2022년 사이였다면 같은 시간에 위 작업의 약 30% 정도, 어쩌면 그보다 적게 했을 것 같다고 함
- 2010년 무렵의 “ancient” Unity에서는 가능했을 수도 있다고 덧붙임
- 회사 규모, 프로세스, 기대치, 커뮤니케이션, 정치 같은 요인이 얽히면 비용을 받는 회사 환경에서 오히려 같은 작업이 느려지거나 중간에 취소될 수 있다고 봄
- Blender가 프로세스가 사람들을 돕기보다 의욕을 꺾고 느리게 만드는 규모·복잡도·워크플로로 가지 않기를 바람
- Blender 4.1은 베타가 되었기 때문에 기능 면에서는 완료 상태이며, VSE 관련 4.1 변경은 현재 release notes 상태로 들어감
- Blender 4.2 작업이 시작되며, 이후에도 명확한 계획 없이 VSE를 계속 만질 생각임
- 진행 상황은 Weekly Updates 포럼 섹션에서 볼 수 있음