2

我是three.js的新手。我一直在通过尝试制作简单的场景并了解官方示例的工作原理来学习three.js。

最近我一直在看https://threejs.org/examples/?q=trans#webgl_materials_physical_transmission,我不明白代码需要在renderer.outputEncoding = THREE.sRGBEncoding这里使用的确切原因是什么。在更简单的场景中,例如将 JPG 作为纹理加载到立方体上,JPG 图像看起来会很好,而无需在渲染器上设置 outputEncoding。

我尝试在谷歌上搜索类似的主题,例如伽马校正,以及人们说大多数在线图像都是在 sRGB 颜色空间中进行伽马编码的东西。但是我自己无法连接所有的点......如果有人能向我清楚地解释这一点,我将不胜感激。

4

1 回答 1

4

如果您不触摸renderer.outputEncoding,则意味着您在应用程序中未使用色彩空间工作流程。引擎假定所有输入颜色值都应该在线性空间中。并且每个片段的最终颜色值不会转换为输出颜色空间。

由于不同的原因,这种工作流程存在问题。一个原因是您的 JPG 纹理很可能是 sRGB 编码以及许多其他纹理。要在片段着色器中计算正确的颜色,重要的是所有输入颜色值都转换为相同的颜色空间(这是线性颜色空间)。如果您不关心色彩空间,您很快就会得到错误的输出颜色。

对于简单的应用程序,这个细节通常并不重要,因为最终图像“看起来不错”。但是,根据您在应用程序中执行的操作(例如,在导入 glTF 资源时),正确的色彩空间工作流程是强制性的。

通过设置renderer.outputEncoding = THREE.sRGBEncoding,您可以告诉渲染器将片段着色器中的最终颜色值从线性转换为 sRGB 颜色空间。因此,您还必须在纹理保存 sRGB 编码数据时告诉渲染器。您可以通过分配THREE.sRGBEncodingencoding纹理的属性来做到这一点。THREE.GLTFLoader对所有颜色纹理自动执行此操作。但是手动加载纹理时,您必须自己执行此操作。

于 2021-11-14T12:41:30.353 回答