首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >three.js gamma校正和自定义着色器

问three.js gamma校正和自定义着色器
EN

Stack Overflow用户
提问于 2014-02-07 22:26:44
回答 2查看 3.1K关注 0票数 5

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

gammaInput =真;gammaOutput =真;

但是,当您编写自己的自定义着色器并从纹理提取颜色时,是否仍然必须将颜色转化为线性空间,或者是否在将纹理上载到THREE.js之前对其进行变换(当gammaInput设置为true时)?

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

谢谢

EN

回答 2

Stack Overflow用户

发布于 2019-10-07 18:33:42

在上载到Three.js 之前,GPU不会将纹理映射到另一个空间。使用块在着色器中就地完成所有操作。

将输入值转换为线性的:

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

代码语言:javascript
复制
texelColor = mapTexelToLinear( texelColor );

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

你明白了吧。

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

代码语言:javascript
复制
#include <encodings_pars_fragment>

然后你需要根据你的纹理所在的空间解码你的纹理。使用sRGB纹理时的示例:

代码语言:javascript
复制
vec4 color = sRGBToLinear(texel);

输出伽马校正值的:

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

代码语言:javascript
复制
#include <encodings_pars_fragment>

然后,您需要包含自动修改frag颜色的块。看看this line吧。

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

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

代码语言:javascript
复制
gl_FragColor = linearToOutputTexel( gl_FragColor );

然后,您可以查看WebGLProgram.js file以了解linearToOutputText函数是如何工作的。这基本上与texel解码的工作方式相同。

希望这是有用的!

票数 3
EN

Stack Overflow用户

发布于 2019-10-06 02:22:44

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

我发现

renderer.gammaOutput = true;

对材质使用自定义着色器时不执行任何操作。您可以通过启用gammaOutput并将gammaFactor设置为极值来测试这一点。内置材质会对此进行响应,但自定义着色器不会。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21630224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档