Three.js中的渲染输出编码(outputEncoding)

2,303 阅读4分钟

起因

事情的起因自一次模型加载事故
最初模型的预览如下:

image.png 但因为笔者设置的问题,模型变成了这样子

image.png

一开始我推测是光照问题,于是给环境打上了几个光源,但我发现无论我怎么调整模型,都无效,所以推测是材质问题
因此也衍生出了第一个解决方案:

改材质

image.png

直接递归搜索模型文件,然后改变其中的网格模型的材质,让其材质可接受光源。 以上可得出结论:

  1. 该模型在3D美术那边设定的材质为不能接受光源
  2. 任何模型,再改变模型后可接受光源

效果:

image.png

这么做确实可以解决问题,但不优雅,难道以后每次加载模型我都得手动更改材质,调整光照? 其实不是的,后经过查证,我找到了解决方案2

修改renderer.outputEncoding

只需要在渲染器那里加一句

  renderer.outputEncoding = THREE.sRGBEncoding;

效果

image.png

为什么这样做可以呢? outputEncoding默认是LinearEncoding,这和sRGBEncoding有什么区别?
先上结论:sRGB简单的来说影响的是传递函数,而这个传递函数影响了色彩的输出

要详细了解究竟是为什么,首先我们得了颜色彩空间的概念
每个颜色空间都是多个设计决策的集合,它们一起选择以支持大范围的色彩,同时满足与精度和显示技术相关的技术限制。在创建 3D 资源或将 3D 资源组合到场景中时,了解这些属性是什么以及一个颜色空间的属性如何与场景中的其他颜色空间相关是很重要的。

参考 CIE 1931 色度图中显示的 sRGB 颜色和白点 (D65)。彩色区域表示 sRGB 色域的 2D 投影,即 3D 体积。资料来源:维基百科

  • 原色: 原色(如红、绿、蓝)不是绝对的;它们是根据可用显示设备的有限精度和能力的限制从可见光谱中选择的。颜色表示为原色的比率。
  • 白点: 大多数色彩空间的设计使得原色R = G = B的等权重总和看起来没有颜色,或“消色差”。消色差值(如白色或灰色)的出现取决于人类的感知,而人类感知又在很大程度上取决于观察者的环境。颜色空间指定其“白点”以平衡这些需求。sRGB 颜色空间定义的白点是 D65
  • 传递函数: 在选择了色域和颜色模型之后,我们仍然需要定义数值与色彩空间之间的映射(“传递函数”)。r = 0.5表示的物理照明是否 比r = 1.0少 50% ?还是普通人眼感知的亮度降低 50%?这些是不同的东西,这种差异可以表示为一个数学函数。传递函数可以是线性的或非线性的,这取决于色彩空间的目标。sRGB 定义非线性传递函数。这些函数有时近似为伽马函数,但术语“伽马”是模棱两可的,在这种情况下应避免使用。

这三个参数——原色、白点和传递函数——定义了一个色彩空间,每个参数都是为特定目标而选择的, 考虑两个非常常见的颜色空间:SRGBColorSpace ("sRGB") 和 LinearSRGBColorSpace ("Linear-sRGB")。两者都使用相同的原色和白点,因此具有相同的色域。两者都使用 RGB 颜色模型。它们仅在传递函数上有所不同——Linear-sRGB 相对于物理光强度是线性的。sRGB 使用非线性 sRGB 传递函数,更接近人眼感知光线的方式和常见显示设备的响应能力。

这种差异很重要。光照计算和其他渲染操作通常必须在线性色彩空间中进行。但是,线性颜色存储在图像或帧缓冲区中的效率较低,并且在人类观察者查看时看起来不正确。因此,输入纹理和最终渲染的图像通常会使用非线性 sRGB 颜色空间。

关于three.js选择sRGBEncoding的最佳实践

最佳实践

  1. 带有颜色数据( .map、.emissiveMap 等)的纹理应配置为.encoding = sRGBEncoding; 所有其他纹理使用LinearEncoding.
  2. 顶点颜色应存储在线性颜色空间中。
  3. 材质.color.emissive应该使用线性色彩空间。值得注意的是,这意味着如果您尝试将场景中的对象与#4285F4HTML/CSS 中的颜色匹配,则材质实际上需要为material.color.setHex( 0x4285f4 ).convertSRGBToLinear(). 浅色也是如此。场景背景颜色和雾色可能是例外?
  4. 如果不使用后期处理,渲染器应该有.outputEncoding = sRGBEncoding,否则使用LinearEncoding并应用伽马校正 (TBD) 作为后期的最后一次传递。

参考

Three.js docs Color-management
Color management in three.js

源码以及模型文件

链接: pan.baidu.com/s/17__2YjiA… 提取码: hxjk