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

标签 android opengl-es glsl shader fragment-shader

在为我的 OpenGL 游戏设置 fragment 着色器时,我发现当物体因远离光源而变暗时,它也会失去不透明度,因为 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 值降低。有没有一种优雅的方法可以将我的 fragment 着色器设置为仅让每个 vec4 颜色点的前 3 个成员受到漫反射的影响?

最佳答案

您可以使用 Swizzling访问颜色 channel 。您可以使用 xyzw,(分别为 r , g, b, as, t, p , q) 分别指的是第一、第二、第三和第四个组件。您可以使用字母的任意组合来创建矢量(例如: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);

关于android - 将 OpenGL fragment 着色器设置为仅通过漫反射减少 vec4 颜色点的 RGB 值,而不是 alpha,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63815800/

相关文章:

java - 将大型交换机转换为哈希(或其他推荐)

java - Libgdx 输入在 Android 上不起作用

android - GLSL 着色器不会从统一变量渲染颜色

opengl-es - OpenGL ES :Purpose of calling glClear on every frame

javascript - 在 threejs 中使用纹理网格和线框网格

opengl - (openGL) 是否应该避免使用不存在的制服的句柄?

c - 如何将纹理存储在内存中并渲染其中的一小部分

android - 使用 for 循环以编程方式将元素添加到 FrameLayout

android - OpenGLES Android 上的噪音屏幕

android - android中的webservice可用性检查