본문 바로가기
vfxai 잡학지식 vfxai 잡학지식

EXR 압축은 정말 무손실일까: DWAA·B44가 값을 바꾸는 경우와 PIZ·ZIP

vfx 잡학지식 읽는 시간 약 10분 조회 9

EXR 압축에서 ZIP·PIZ는 실측한 픽셀 값이 그대로였지만, DWAA와 B44는 HALF 데이터 값을 바꿨습니다. 512×512 Position형 이미지에서 HALF DWAA는 최대 7.5, 평균 0.4406의 RGB 오차를 냈고 알파는 변하지 않았습니다. 수치 보존이 중요한 AOV라면 압축 이름만 보고 결정하지 말고 저장 후 값을 확인해야 합니다.

Blender 5.0.0 백그라운드에서 HDR 하이라이트가 있는 beauty형 RGBA와 -500~500 좌표 값을 담은 Position형 RGB를 각각 만들고, HALF·FLOAT로 저장한 뒤 다시 읽어 비교했습니다. HALF 결과는 원본을 HALF로 양자화한 값과 비교해 데이터형 변환과 압축 영향을 나눴습니다. 합성 이미지 한 쌍의 결과이므로 다른 렌더에서는 수치가 달라질 수 있습니다.

이미지저장형코덱파일 크기 (KiB)RGB 최대 오차RGB 평균 오차변경 픽셀알파 최대 오차
Beauty RGBAHALFZIP1,065.1000%0
Beauty RGBAHALFPIZ1,088.1000%0
Beauty RGBAHALFDWAA587.10.1796880.00174399.997%0
Beauty RGBAHALFB44896.70.2343750.00036299.298%0.001938
Position RGBHALFZIP149.7000%0
Position RGBHALFPIZ500.2000%0
Position RGBHALFDWAA131.17.5000000.44063899.857%0
Position RGBHALFB44896.71.9550780.00406222.870%0
Beauty RGBAFLOATZIP3,570.3000%0
Beauty RGBAFLOATPIZ3,535.8000%0
Beauty RGBAFLOATDWAA815.90.1799710.001744100%0
Beauty RGBAFLOATB44지원 안 함지원 안 함지원 안 함지원 안 함지원 안 함
Position RGBFLOATZIP2,148.1000%0
Position RGBFLOATPIZ2,366.8000%0
Position RGBFLOATDWAA131.27.5874020.442597100%0
Position RGBFLOATB44지원 안 함지원 안 함지원 안 함지원 안 함지원 안 함

오차는 RGB 채널의 절대 오차이며, 변경 픽셀은 RGB 중 하나 이상의 값이 달라진 픽셀 비율입니다. 알파 열은 알파 채널의 최대 절대 오차입니다. Blender 5.0.0에서는 FLOAT 저장에 B44·B44A를 선택할 수 없었습니다.

EXR 압축에서 무엇을 비교해야 할까요?

Viewer에서 차이가 보이지 않는다고 픽셀 값까지 같다고 볼 수는 없습니다. 반대로 화면 차이가 생겼다고 압축만을 원인으로 단정할 수도 없습니다.

비교할 대상은 저장 전 원본과 저장 후 다시 읽은 픽셀 값입니다. 같은 위치와 같은 채널을 비교하고, 해상도·채널 구조·데이터형·색 처리를 유지해야 합니다.

값이 달라졌다면 세 가지를 나눠 확인합니다.

  • 데이터형 변환: FLOAT에서 HALF로 바뀌었는지 확인합니다.
  • 압축 손실: 선택한 코덱이 해당 채널에 손실 처리를 하는지 확인합니다.
  • 색 처리 변경: 저장 과정에서 색공간이나 프리멀티플라이가 바뀌었는지 확인합니다.

무손실 압축도 저장 전에 발생한 데이터형 변환이나 색 처리까지 되돌리지는 않습니다. 데이터 표현 자체의 차이는 비트뎁스별 데이터 표현을 정리한 글에서 확인할 수 있습니다.

같은 원본으로 코덱만 바꿔 비교합니다

OpenImageIO의 oiiotool에서 출력 압축을 지정한 뒤, idiff로 디코딩된 픽셀을 비교할 수 있습니다.

oiiotool source.exr --compression zip -o zip.exr
oiiotool source.exr --compression piz -o piz.exr
oiiotool source.exr --compression dwaa -o dwaa.exr
oiiotool source.exr --compression b44 -o b44.exr

모든 출력은 같은 source.exr에서 만들어야 합니다. exrheader로 compression, 채널 데이터형, 해상도와 part 구성이 유지됐는지 확인합니다. 설치된 OpenImageIO와 OpenEXR 버전에 따라 지원 코덱이 다를 수 있으므로 실제 파일 헤더를 확인해야 합니다.

idiff -a source.exr zip.exr
idiff -a source.exr piz.exr
idiff -a source.exr dwaa.exr
idiff -a source.exr b44.exr

idiff -a는 모든 subimage를 비교합니다. 결과에서 최대·평균 오차와 경고·실패 임계값을 넘은 픽셀 수를 확인합니다. 임계값 이하의 작은 차이는 집계에 포함되지 않으므로, 변경 픽셀 전체 비율은 별도로 계산해야 합니다. 해상도나 채널 수가 다르면 비교가 중단될 수 있으므로 먼저 구조를 맞춥니다.

AOV의 용도에 따라 허용할 손실을 정합니다

  • 최종 beauty: 시각적 차이가 허용되는지 샷별로 검증한 뒤 손실 압축을 선택할 수 있습니다.
  • Z-depth·normal·motion vector: 후속 계산에 쓰이는 수치이므로 값 보존을 우선합니다.
  • ID·Cryptomatte·utility AOV: 데이터 정확성이 중요하므로 무손실 저장을 기본으로 검토합니다.

화면에서 차이가 작아도 깊이 계산이나 벡터 기반 처리 결과는 달라질 수 있습니다. 반복적인 Grade, Merge, 키잉이나 블러에 쓰는 beauty도 저장 단계의 작은 오차가 후속 작업에 영향을 줄 수 있습니다.

PIZ 압축과 ZIP 압축은 값을 보존합니다

OpenEXR 공식 Technical Introduction은 PIZ와 ZIP을 무손실 압축으로 설명합니다. 압축 전 데이터형과 픽셀 값이 다른 처리로 바뀌지 않았다면, 압축을 풀었을 때 원래 값을 복원합니다.

  • PIZ: 웨이블릿 변환과 Huffman 부호화를 사용합니다. 압축 효율은 이미지 내용과 타일 크기에 따라 달라집니다.
  • ZIP: 인접 픽셀 차이를 활용해 deflate로 압축합니다. 16개 스캔라인 단위로 처리합니다.
  • ZIPS: ZIP 계열이며 1개 스캔라인 단위로 처리합니다.

PIZ가 항상 ZIP보다 작거나 빠르지는 않습니다. 특정 렌더의 파일 크기와 읽기 속도는 실제 작업 파일로 확인해야 합니다.

DWAA 압축은 채널 분류에 따라 값을 바꿉니다

DWAA는 RGB 데이터에 DCT를 적용하고 계수를 양자화하는 손실 압축입니다. DWAA는 32개, DWAB는 256개 스캔라인을 한 블록으로 처리합니다.

OpenEXR 기본 분류 규칙에서는 채널 이름과 데이터형에 따라 처리 방식이 달라집니다.

  • R·G·B 및 색상으로 분류된 채널: 손실 DCT 압축 대상입니다.
  • A 채널: 기본적으로 무손실 RLE로 처리합니다.
  • Z·depth·velocity 등 기본 채널: 기본적으로 ZIP 방식으로 처리합니다.

이 규칙은 변경할 수 있습니다. 데이터 AOV라도 utility.R, utility.G, utility.B처럼 RGB로 분류되면 손실 대상일 수 있으므로 실제 채널 구성과 저장 결과를 확인해야 합니다.

DWAA level을 0으로 두면 무손실일까요?

OpenEXR DWA 구현은 기본 압축 level을 45.0으로 설명합니다. FLOAT 입력은 먼저 HALF로 양자화한 다음 DWA 처리를 진행하므로 값이 달라질 수 있습니다. FLOAT와 HALF의 표현 차이는 32bit Float 이미지 설명에서 확인할 수 있습니다.

level 0은 계수 양자화 단계의 추가 양자화를 줄이지만, 색공간 변환이나 DCT 과정의 양자화까지 없애지는 않습니다. 따라서 level 0도 무손실을 보장하지 않습니다. “visually lossless”라는 표현도 값이 정확히 같다는 뜻은 아닙니다.

B44 압축은 HALF 채널의 값을 바꿉니다

OpenEXR 공식 문서에 따르면 B44는 HALF 채널을 4×4 픽셀 블록으로 묶어 압축합니다. 일반 블록은 32바이트에서 14바이트로 줄고, B44A는 블록의 값이 모두 같을 때 3바이트로 저장할 수 있습니다.

B44는 HALF 채널을 손실 압축 대상으로 삼습니다. 따라서 색상뿐 아니라 HALF로 저장한 알파와 유틸리티·AOV 채널도 값이 달라질 수 있습니다. FLOAT와 UINT 채널은 B44 압축 대상이 아니며, B44와 B44A는 deep 파일을 지원하지 않습니다.

근거표에서 확인한 OpenEXR 소스의 2026-10-10 commit 주석은 B44 압축 전에 NaN과 무한대(Inf)를 0으로 대체한다고 설명합니다. 이 내용은 해당 구현 주석의 범위로 한정합니다.

EXR 압축 방식별 채널 처리: PIZ·ZIP 무손실, DWAA·DWAB는 RGB 손실과 A·Z 기본 무손실 경로, B44는 HALF 채널 손실과 FLOAT·UINT 비압축
OpenEXR 기본 규칙에 따른 채널 처리 개념도입니다. ZIP·PIZ는 픽셀 값을 보존하고, DWAA·DWAB와 B44는 채널 이름과 데이터형에 따라 손실 여부가 달라집니다. 위 실측에서도 DWAA는 알파를 그대로 두었고, B44는 HALF 알파까지 바꿨습니다.

수치 보존이 필요하면 ZIP·PIZ를 우선합니다

ZIP과 PIZ는 실측에서 값을 보존했고, DWAA와 B44는 HALF 이미지 값을 바꿨습니다. 따라서 모든 AOV의 수치 보존이 필요하면 ZIP이나 PIZ를 우선하고, DWAA·B44는 실제 채널과 디코딩 결과를 확인한 뒤 선택합니다.

최종 beauty처럼 시각적 차이가 판단 기준인 경우에도 샷과 후속 작업에 맞춰 검증합니다. 압축 방식만으로 특정 렌더의 파일 크기나 성능을 보장할 수는 없습니다.

결국 확인할 것은 파일이 작아졌는지가 아니라, 저장 뒤에도 합성에 필요한 픽셀 값이 남아 있는지입니다. 같은 원본에서 압축만 바꾸고 헤더와 디코딩된 값을 비교한 다음 선택합니다.

vfx 잡학지식

함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.