将 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

在为我的 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 启用了透明度,我的不透明纹理对象在光线较暗或法线视线较高时呈现为透明,因为 alpha 也随着 RGB 值降低。有没有一种优雅的方法可以将我的片段着色器设置为仅让每个 vec4 色点的前 3 个成员受到漫反射的影响?

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

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

如果在相同类型的向量之间使用二元运算符(如 *),则它们有效 component-wise(例如 v_Color * vec4(...))。
二元运算符也可用于将 floating-point 值运算到向量的所有分量(例如 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);