我正在使用FFmpeg将游戏的线性深度缓冲区写入openEXR。不幸的是,FFmpeg没有完全遵守openEXR文件规范(例如允许一个通道使用无符号整数),因此我将一个浮点通道写入openEXR,并使用以下命令将其放入绿色通道:
浮点范围为0F到1F,并且是线性的。通过在Blender合成器中测试16位整数(每像素组件),我可以确认计算和线性化是正确的。对于16位整数数据,写入方式如下:
然而,在查看openEXR文件时,它与16位png文件的“渐变”不同...并且在并排查看它们时,似乎接近0的值不是线性的,并且它们不像16位png那样暗。 (是的,我将图像节点设置为线性),并且与游戏的3D跟踪数据进行比较,我无法重现深度并且无法使用深度缓冲区屏蔽物体,但是使用png文件则可以。
在图像中,线性浮点范围如何变得与线性整数范围如此不同呢?
更新:
我现在使用以下代码向FFmpeg写入3个通道。
字节缓冲区的大小为
FFmpeg似乎正在分离通道或其他操作...可能是一个错误,也可能是我的问题?
-f rawvideo -pix_fmt grayf32be -s %WIDTH%x%HEIGHT% -r %FPS% -i - -vf %DEFVF% -preset ultrafast -tune zerolatency -qp 6 -compression zip1 -pix_fmt gbrpf32le %NAME%_depth_%d.exr
。浮点范围为0F到1F,并且是线性的。通过在Blender合成器中测试16位整数(每像素组件),我可以确认计算和线性化是正确的。对于16位整数数据,写入方式如下:
short s = (short) (linearzieDepth(depth) * (Math.pow(2,16) - 1))
。而对于浮点数,线性化值直接写入OpenEXR而不乘以任何值。然而,在查看openEXR文件时,它与16位png文件的“渐变”不同...并且在并排查看它们时,似乎接近0的值不是线性的,并且它们不像16位png那样暗。 (是的,我将图像节点设置为线性),并且与游戏的3D跟踪数据进行比较,我无法重现深度并且无法使用深度缓冲区屏蔽物体,但是使用png文件则可以。
在图像中,线性浮点范围如何变得与线性整数范围如此不同呢?
更新:
我现在使用以下代码向FFmpeg写入3个通道。
float f2 = this.linearizeDepth(depth);
buffer.putFloat(f2);
buffer.putFloat(0);
buffer.putFloat(0);
字节缓冲区的大小为
width * height * 3 * 4
,即每个通道占用4个字节的3个通道。现在的命令是-f rawvideo -pix_fmt gbrpf32be -s %WIDTH%x%HEIGHT% -r %FPS% -i - -vf %DEFVF% -preset ultrafast -tune zerolatency -qp 6 -compression zip1 -pix_fmt gbrpf32le %NAME%_depth_%d.exr
,这意味着输入(字节缓冲区)期望使用32位浮点数和3个通道。![This is how it turns out](https://istack.dev59.com/8RtrB.webp)