将 OpenGL 片段着色器设置为仅通过漫反射减少 vec4 色点的 RGB 值,而不是 alpha

Posted

技术标签:

【中文标题】将 OpenGL 片段着色器设置为仅通过漫反射减少 vec4 色点的 RGB 值,而不是 alpha【英文标题】:Setting OpenGL fragment shader to reduce only the RGB values of the vec4 color points by the diffuse, not the alpha 【发布时间】:2020-09-09 16:28:17 【问题描述】:

在为我的 OpenGL 游戏设置片段着色器时,我发现当一个对象因远离灯光而变暗时,它也会失去不透明度,因为 gl_FragColor 计算会影响色点的所有四个成员:

GLES20.glEnable(GL_BLEND);
GLES20.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

final String Light1fragmentShader  = 
...
"varying vec4 v_Color;" +
...
"void main()" +""  +
...
"gl_FragColor = v_Color * diffuse * texture2D(u_Texture, v_TexCoordinate);" +
...

由于我的游戏通过 GL_BLEND 启用了透明度,因此当光线较暗或正常视线较高时,我的不透明纹理对象呈现为透明,因为 RGB 值也会降低 alpha。有没有一种优雅的方法可以将我的片段着色器设置为仅让每个 vec4 色点的前 3 个成员受漫反射影响?

【问题讨论】:

【参考方案1】:

您可以使用Swizzling 访问颜色通道。您可以使用xyzw,(分别为rgbaspq) 分别指第一个、第二个、第三个和第四个组件。您可以使用任意字母组合来创建向量(例如:texColor.rgb):

vec4 texColor = texture2D(u_Texture, v_TexCoordinate);
gl_FragColor = v_Color * vec4(diffuse * texColor.rgb, texColor.a);

如果在相同类型的向量之间使用二元运算符(如 *),它们将按组件工作(如 v_Color * vec4(...))。 二元运算符还可用于对向量的所有分量进行浮点值运算(例如diffuse * texColor.rgb)。 (进一步查看GLSL Programming/Vector and Matrix Operations)

向量可以由其他向量或向量和标量的组合构成(例如vec4(vec3(...), texColor.a))。见Vector constructors。


或者,您可以从 diffuse 创建一个 3 分量向量并构造一个 4 分量向量,其中第 4 个分量是 1 (vec4(vec3(diffuse), 1.0)):

gl_FragColor = 
    v_Color * vec4(vec3(diffuse), 1.0) * texture2D(u_Texture, v_TexCoordinate);

【讨论】:

两个优雅的解决方案,带有示例。这就是我喜欢 *** 的原因。我很久以前学习的 OpenGL 教程应该使用您的片段着色器方法。

以上是关于将 OpenGL 片段着色器设置为仅通过漫反射减少 vec4 色点的 RGB 值,而不是 alpha的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL,漫反射着色器

实现每个顶点的漫反射着色器,不起作用

OpenGL/C++:将多个纹理传递给一个着色器的问题

OpenGL 3着色器错误[关闭]

光照 漫反射光照

光照 漫反射光照