【问题标题】:three.js gamma correction and custom shadersthree.js 伽玛校正和自定义着色器
【发布时间】:2014-02-07 14:26:43
【问题描述】:

我不太确定 THREE.js 如何在内部处理伽马校正。 似乎要启用它,您唯一需要做的就是在渲染器对象上设置以下标志:

伽马输入=真; gammaOutput = true;

但是,当您编写自己的自定义着色器并从纹理中获取颜色时,您是否仍然需要将颜色转换为线性空间,或者 THREE.js 是否在将纹理上传到 GPU 之前对其进行转换(当 gammaInput 设置时为真)?

同样地,当在着色器中确定最终颜色时,是否必须将其转换为伽马空间,或者是否存在 THREE.js 自动应用的后期处理效果(当 gammaOutput 设置为 true 时)?

谢谢

【问题讨论】:

标签: three.js webgl


【解决方案1】:

Three.js 在上传到 GPU 之前不会将您的纹理映射到另一个空间。一切都使用块在着色器中就地完成。

将输入值转换为线性:

作为一个例子,看看 Three.js 如何处理 map 属性 here。你基本上会看到这一行:

texelColor = mapTexelToLinear( texelColor );

mapTexelToLinear基本上是在WebGLProgram.js file中创建的。

你明白了。

总而言之,您基本上可以在着色器顶部包含this chunk

#include <encodings_pars_fragment>

然后你需要根据你的纹理所在的空间来解码你的纹素。例如,如果你使用 sRGB 纹理:

vec4 color = sRGBToLinear(texel);

输出伽马校正值:

您还需要在着色器顶部包含encodings_pars_fragment

#include <encodings_pars_fragment>

然后您需要包含自动修改碎片颜色的块。看看this line

通过在自定义着色器末尾包含块 encodings_fragment,它将根据您在 THREE.WebGLRenderer 上使用的参数自动映射您的片段。

要了解这项工作的原因,您可以查看encodings chunk,其中仅包含:

gl_FragColor = linearToOutputTexel( gl_FragColor );

然后您可以查看WebGLProgram.js file 以了解linearToOutputText 函数的工作原理。这与纹素解码的工作方式基本相同。

希望这有用!

【讨论】:

    【解决方案2】:

    虽然我相信 https://github.com/mrdoob/three.js/issues/1488 回答了您的第一个问题,但您的第二个问题仍未得到回答。

    我发现了

    renderer.gammaOutput = true;

    当您为材质使用自定义着色器时,不会做任何事情。您可以通过启用gammaOutput 并将gammaFactor 设置为一个极值来对此进行测试。内置材质会对此做出响应,但您的自定义着色器不会。

    所以是的,在这种情况下,您需要自己处理 gamma,方法是修改输出颜色,或者在您在线性空间中完成所有渲染后添加一个后期处理步骤。

    【讨论】:

      猜你喜欢
      • 2018-12-04
      • 2022-12-10
      • 1970-01-01
      • 1970-01-01
      • 2019-10-05
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 2012-10-12
      相关资源
      最近更新 更多