JPEG XL as an intermediate format

Hi! I hope that I’m allowed to post in this section.

Regarding JPEG-XL’s use cases, it would be highly appreciated if you could consider its potential as an intermediate image format. It can store up to 4099 32 bit float channels with very efficient lossless or lossy compression.

While big studios no doubt will still prefer EXR for a while, JXL would finally make 32 bit multilayer image sequences affordable to use on AWS for hobbyists like myself.

For now I’m very happy that the format made it onto the roadmap.

4 Likes

I’d also like to show my support for JpegXL, the prospect of EXR-like data transfer, without EXR-like file sizes would be a game changer for me.

1 Like

Has anyone done a comparison of JPEG XL and OpenEXR DWAA/DWAB, for use as an intermediate format? I couldn’t find anything good.

The appropriate compression algorithms for intermediate and final image format might be different, since for compositing you need to preserve more than what you see. If you change exposure up or down you may find important detail has been thrown away.

It also wasn’t immediately obvious to me if there is a way to compress channels with different compression levels, for passes that need more precision.

JPEG XL as far as I know was not designed for this purpose while OpenEXR DWAA was. It might still work, but would need to be confirmed before we consider it as an intermediate format in Blender on the same level as OpenEXR.

Note that since Blender 4.4 there is a quality slider for OpenEXR DWAA which lets you control how lossy it is. The next version of OpenEXR will also have a new lossless compression.

4 Likes

Regarding its suitability as an intermediate format, JXL has been found suitable as a codec for the DNG camera raw format. Although not the same use case as render passes, it also needs to preserve imperceptible details in this use case.

Regarding individual quality settings per channel, I’m not sure how the format specification handles this, and how it is implemented in libjxl at the moment. Ideally you would want to get in touch with Jon Sneyers from Cloudinary, who is one of the JXL format’s developers, and the most publicly active of them.

Even if Blender only got single layer JXL files for now, it would in my opinion already be worth it, since there currently is no 32 bit float image format that produces such small file sizes.

I made some non-scientific observations about JXL on right-click-select in the past, but decided to try some more reproducible tests. While probably not conclusive, I hope that this can show some of the capabilities. I chose PolyHaven’s Shed scene for this, because it’s publicly available and has a high dynamic range, with many low light areas.

I failed to update the used CJXL version before testing. The used version is 0.10.2, while 0.11.1 is available.

First, I’m a bit limited due to the current JPEG-XL reference implementation:

  1. It currently can’t handle 32 bit float EXR input files, only 16 bit float. This is a known issue that is not related to the JXL specification itself: cjxl generates 16-bit float from 32-bit float exr input · Issue #465 · libjxl/libjxl · GitHub
    During my tests it seemed as if DWA only uses 16 bit float precision, so I saved both, DWA and JXL files in 16 bit float.

  2. The reference implementation can’t handle multilayer EXR files and greyscale EXR files, so all passes were saved as separate RGB EXR files, selecting “Non-Color” for non-color passes.

First I want to test JXL’s lossless mode, since this doesn’t require me to judge image quality. For the test, I rendered PolyHaven’s Shed scene in 1920x1080 resolution, using the scene’s supplied settings, except for using blue noise. The compositor was disabled, and the exported render passes were: Combined, Depth, Denoising Albedo, Denoising Depth, Denoising Normal.

DWA:

  1. The render result was saved as a 16 bit float multilayer EXR file, using DWAB at 90% quality. (I used DWAB for my tests, because it produces smaller files.)
  2. The resulting EXR file had a size of 35.0 MiB.

JXL:

  1. The render result was saved as an uncompressed 16 bit float multilayer EXR file.

  2. The uncompressed multilayer EXR file was loaded in the compositor and all 5 render passes were one after the other connected to the composite output, to extract individual passes, and save them as separate uncompressed 16 bit float single layer EXR files. Due to the above mentioned limitations, depth passes were saved as RGB files. All non-color passes had their color management set to “Non-Color” in the save dialog.

  3. All 5 single layer EXR files were converted using CJXL, with the quality setting “-d 0.0”, which produces lossless files.

  4. The 5 resulting JXL files had a combined size of 20.3 MiB.

  5. All 5 JXL files were converted back to EXR and loaded in the compositor.

  6. All 5 back-converted files were visually verified against the original uncompressed EXR files using a mix node with difference blending, and an RGB curves node amplifying the output.

  7. All 5 comparisons showed no difference, so the compression appears to have been lossless.

  8. Optional: Compressing the combined pass at slightly lossy quality “-d 0.05” while keeping the other passes lossless, resulted in a combined file size of 15.1 MiB.

Even using lossless compression, JXL produced a smaller data size than the lossy DWAB EXR file. Most likely it was extremely efficient at compressing the Depth and Denoising passes.

For a second test, I tried to compare the lossy performance of DWAB and JXL, using only the noisy combined pass.

DWA:

  1. The combined pass was saved as a 16 bit float single layer EXR file, using DWAB at 70% quality.
  2. The resulting EXR file had a size of 1.8 MiB.

JXL:

  1. The combined pass was saved as an uncompressed 16 bit float single layer EXR file.
  2. This EXR file was then converted to JXL using CJXL with the quality setting “-d 0.1”, which was chosen because its 1.7 MiB file size was close to the DWA compressed file.
  3. The JXL file was converted back to an uncompressed 16 bit float EXR file, so that it can be loaded in Blender for comparison.

Comparison:

  1. The original uncompressed 16 bit float EXR file was loaded in the compositor.
  2. The DWAB compressed EXR file was loaded in the compositor.
  3. The EXR file that was back-converted from the lossy JXL file was loaded in the compositor.
  4. Color mix nodes with difference blend mode were used to compare the lossy EXR files to the original. RGB curves clipped from 0.0 to 0.1 were used to make the differences more visible.
  5. The DWAB comparison showed a lot of uniform noise, meaning that DWAB removed a lot of the render noise.
  6. The JXL comparison showed much less differences, with some blocks visible in specific areas.
  7. Viewing the lossy files directly and increasing contrast in those areas using RGB curves however showed no noticeable artifacts.
  8. The output of both comparisons was mapped to the red and green channels of a combine color node, to generate an image that shows the DWAB difference in the green channel and JXL difference in the red channel. This means that green areas show up were DWAB performed worse, red areas were JXL performed worse, and yellow areas where they match.
  9. The color comparison showed most of the areas with noticeable JXL block artifacts in yellow, with little orange and red visible.

I uploaded the test files here: Proton Drive

While this test just scratches the surface, I think JXL looks very promising. For denoised Cycles renders, I found that lossy JXL compression artifacts look a lot like denoising artifacts, so renders could be compressed a lot before compression artifacts became distinguishable from denoising artifacts. However this is much more subjective so I didn’t include it for now.

3 Likes

Thanks for the extensive tests. I’ve moved this to a new post so it will be easier to find in the future.

For reference, the next version of OpenEXR will include lossless compression using htj2k (openjph). I’m not sure how it compares to jxl on 16 / 32 bit float images. This website gets referenced in OpenEXR discussions but it seems to only go up to 10 bit.
https://www.lossless-benchmarks.com

4 Likes