UE外部贴图颜色还原测试与OCIO配置

如何让一张外部贴图在UE里显示原本的颜色?

本测试主要解决两个问题:

  • 外部输入的 EXR 和内部的场景线性数据如何实现一样的处理效果?
  • 外部数据如何精确地复现在 8bit 的显示器上?

我制作了一个 EXR(线性编码)的图片,这个图片有两个蓝色,一个是 0 0 255 的纯蓝色,一个是 0 0 0.75 的蓝色。

同样的,我在内部通过自发光材质也建立了两个这样的蓝色:0 0 255 的自发光蓝色和 0 0 0.75 的蓝色。

一张从外部导入的贴图如何保证和内部渲染的码值一致?

测试设置

当我将该图片(HDR_TV_Float.exr)的输入调整为如下压缩设置:

压缩设置
EXR 贴图压缩设置

EXR 输入的时候,选择线性编码

编码设置
EXR 编码设置(选择线性编码)

这个 Encoding Override 是 Gamma 调整,因为图片是 EXR 线性的,所以这里选择 Linear 选项。

这里的 ColorSpace 设置为 None(默认为项目中设置的工作色域),如果这里的设置和项目设置一样,也是不会做色域转换的。

这里测试,使用工作色域 sRGB,选择 None,不做色域转换。

测试结果

得到的结果:外层是自己建的自发光材质,中间是测试图(模拟 xR 工作流程中输入的一张图片),根据图片显示,所有的数据都对应在了一起,在此时已经是一样的了。

说明在这个设置下,我们能保证 UE 内部生成的码值能和外部输入的码值对应起关系(消除了图片输入的 Gamma)。

测试结果对比
外部输入码值与内部自发光材质码值对比

以下是部分码值显示的情况:

码值对照表(配置 OCIO 前)

外部码值(浮点)外部码值

(原图码值、或称为“原始码值”,即图像编码时候的码值,使用EXRView进行读取  也是图上自定义材质生成的颜色)
Texture 页面码值(8bit)在Texture页面显示的码值(使用微信截图获取8bit的显示数据) View 窗口码值(8bit)
在view窗口上显示的码值 (自发光材质、使用微信截图获取8bit的显示数据,view显示功能关闭如下)同时关闭所有场景中的灯光(仅仅因为做测试的需要,这个在实际生产中可以关闭交给LUT去做校准)。image.pngimage.png
View 显示(8bit 截图,自发光材质)
0 0 1 纯蓝色 0 0 255 0 0 255
0 0 0.75 半蓝色 0 0 255 0 0 224
1 0 0 红色 255 0 0 255 0 0
0.75 0 0 半红色 255 0 0 224 0 0
0.75 0 0.75 紫色 255 0 255 224 0 224
0.02 0.02 0.02 2%灰 39 39 39 43 43 43
0.04 0.04 0.04 4%灰 56 56 56 59 59 59
  • 外部码值:原图码值(即”原始码值”,图像编码时候的码值,使用 EXRView 读取,也是图上自定义材质生成的颜色),使用浮点数标识。
  • Texture 显示:在 Texture 页面显示的码值(使用微信截图获取 8bit 的显示数据)。
  • View 显示:在 view 窗口上显示的码值(自发光材质,使用微信截图获取 8bit 的显示数据,view 显示功能关闭,同时关闭场景中所有灯光——仅为做测试的需要,实际生产中可以交给 LUT 去做校准)。
测试场景层级
测试场景层级(Outliner)
视口显示功能开关
视口显示功能开关(Show Flags,关闭 Bloom、Tone Curve 等后处理)

从实验中获得的信息

  1. 当正确输入(线性化)EXR 的编码之后,它的处理逻辑和内部生成的场景线性的处理逻辑是一样的(外部为 0 的码值和内部 0 的码值在渲染过后的结果是一样的)。能保证内部的码值和外部的码值处于同样的处理状态(都转换成线性的进行工作)。

  2. 在原始码值与 Texture 显示窗口显示数据和渲染 View 显示数据显示出来的码值不一致,为什么?

    • Texture 显示窗口:包含了未知转换(方便用户观看),不能相信。
    • 渲染 View 显示数据:能明确知道它在 Unlit 情况下用了什么样的显示转换——通过 OCIO,所以可以明确知道渲染管线上有什么。
    • 原始码值:是一切的起点,理想情况下应该显示出这个颜色。

对于 xR 而言,要保证的是原始码值渲染 View 显示数据上的码值的一致性。

为什么码值在视口里和外部不一致?

为什么这张图在外部的码值是 0.75(换算成 8bit 约为 191),输入引擎之后却变成了 224?(如上测试中的半蓝色、半红色)

这是因为当前显示出来的数据还是线性数据,它没有被正确地对应我们的屏幕、还原出来。当前内部显示还是 Rec.709 的线性数据,要让它正确显示,需要配置渲染 View 的 OCIO。

OCIO 配置

OCIO 的工作空间选择 WorkingColorSpace 或是 Linear Rec709(SRGB)。输出选择 sRGB - Display - RAW 标准版本的 sRGB。

OCIO 配置
OCIO 工作空间与输出配置(sRGB - Display - Raw)

配置 OCIO 后的码值对照表

外部码值(浮点)
(原图码值、或称为“原始码值”,即图像编码时候的码值,使用EXRView进行读取  也是图上自定义材质生成的颜色)

使用浮点数进行标识
View 窗口码值(8bit,配置 OCIO 后)

使用微信截图获取8bit的显示数据,view显示功能关闭如下)

image.png
View 显示(8bit 截图,自发光材质)
0 0 1 纯蓝色 0 0 255
0 0 0.75 半蓝色 0 0 191
1 0 0 红色 255 0 0
0.75 0 0 半红色 191 0 0
0.75 0 0.75 紫色 191 0 191
0.02 0.02 0.02 2%灰 5 5 5
0.04 0.04 0.04 4%灰 10 10 10

完美还原原始的码值。

UE 渲染逻辑(参数影响)研究

发现 UE 的各种渲染设置也会很大程度上影响到渲染的颜色效果,所以按照类别分别讨论每一个参数对于渲染效果的影响。

后处理 - Exposure 类

每种曝光设置的逻辑和影响的区别(待补充)。

后处理 - Highlight Contrast / Shadow Contrast

Highlight Contrast / Shadow Contrast
Highlight Contrast / Shadow Contrast 参数效果

后处理 - Tone Curve Amount

Tone Curve Amount
Tone Curve Amount 参数效果

后处理 - Expand Gamut

Expand Gamut
Expand Gamut 参数效果