首页 > 代码库 > HDR Image encoding formats
HDR Image encoding formats
HDR图像的编码与存储是PRBT、IBL中的一个重要问题。其主要是将scene-referred的颜色信息存储并保存后在渲染时进行使用,然后通过tone-mapping这样的操作将其映射到output-referred的R8G8B8的颜色值并输出到终端显示器上。当然,一般来说不需要直接存储并读取HDR图像,但如果要实现一些PBRT的效果或是一个自己的LightMap baker的话,那么HDR的存取就是必不可少的了。这里总结一下HDR的存储编码格式。
主要有以下三种格式:
- HDR;对应的编码方式主要是RGBE/XYZE
- TIFF;对应的编码方式主要是RGB/LogLuv24/LogLuv32
- EXR;对应的编码方式主要是HalfRGB
1. HDR格式
其编码方式为RGBE,即通过ldr的rgb值,配合一个该组值对应的exponent来还原最初的HDR颜色信息。在一个32bits的RGBE中,通常是R8G8B8E8的占位方式。假设场景中的原始scene-referred的颜色为RsGsBs,那么将其向RGBE的映射操作如下式所示:
对于由RsGsBs到RGB的还原对上述计算进行逆操作即可。
XYZE与RGBE类似,只不过其存储与编码的是XYZ空间中的颜色值,而不是RGB空间。由于XYZ空间中不需要存储负值(RGB与XYZ颜色空间的区别),因而使用上述only positive的方法来存储的话使用XYZE会比RGBE得到更大的色域,因为不会存储无效值。
2. TIFF格式
基本的TIFF存储格式比较简单,直接使用3个32bits的RGB通道来存储原始的信息,因而永远是scene-referred的。但是这种方式太过于简单,占用空间太大并且无法进行有效的数据压缩(压缩算法对于3个float的数值压缩比不高),因而就有了基于其的改进方法,LogLuv24、LogLuv32。
LogLuv的方法是将一个颜色值转化为luminace(Y)及其对应的u、v值来存储,即Luv空间。Luv空间是RGB与XYZ之后的另外一个颜色空间,其与XYZ、RGB均可以进行相互转换,其空间内的颜色值具有的特点是可以直接通过Luv之间的欧氏距离而得到两个颜色之间的差异程度,因而在图像处理与识别中很有用。注意,这里的原始scene-referred空间为XYZ,因而在存储与解析时就涉及到XZY-Luv之间的转换(转换操作可以看这里);
- LogLuv24:一个颜色值用24bits进行存储,其中的bit分割为:L10、C14。其中的L10即中将Luminace值(即XYZ空间中的Y值)转化为一个log函数映射的10bits浮点数进行存储;C14为uv中的u值通过14bits进行保存的一个浮点数。这里由于只存储了uv中的一个值,因而另外v值需要通过一个uv查询表获得,这样就需要在LogLuv24的存储与解码时均需要使用这样的一个uv对应表来协助完成。
- LogLuv32:一个颜色值通过32bits进行存储,其中的bit分配为:s1、L15、u8、v8。其中的s1为符号位,用来标识Luminace值的正负情况(当然,由XYZ空间转换过来的一定为正);L15为15个bit位的L值 ;u8、v8分别为两个byte表示的uv值,这里就不再需要查uv表了。
3. EXR格式
Exr格式由ILM给出的HDR存储格式,现基本上已经成为影视产业中HDR应用的一个标准格式。其本质上是使用half格式的浮点数来存储RGB值,因而需要占用48bits的存储空间。Half的浮点存储格式即是S5E10M,没有太多好说的。关于exr格式的HDR编解码,现在有开源的的OpenExr可以用,其中还包含了对exr格式的压缩等操作,各种使用exr的引擎或renderer中使用的都是它,比如unity、blender、pbrt。
上述三种主流的HDR存储各有优劣,比如RRGE的读解析比较简单、LogLuv在图像识别中的应用比较方便,EXR的half存储与现在的GPUshader计算比较兼容等;同时它们也有不同的存储空间与编解析速度。但是,一般情况下,我们在引擎或项目中应用还是要根据具体情况来选用相应的格式。同时,理解HDR的不同存储,以及其背后的color space原理,将使得对于image based lighting的掌握会变得更加的容易。