gpt4 book ai didi

java - OpenGL ES 2.0 : Alpha value in fragment shader is ignored (using glReadPixels())

转载 作者:行者123 更新时间:2023-12-01 18:40:12 28 4
gpt4 key购买 nike

我正在尝试在 Android 上使用 OpenGL ES 2.0 显示一个非常简单的东西(至少我是这么认为的):具有透明度的单色四边形。我的 fragment 着色器基本上就是这样做的:

gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);

因此,四边形应显示为纯红色,但透明度为 50%,以便背景(黑色)透过,这会使其稍微暗一些。然而,无论我为 vector 中的 Alpha channel 元素选择什么值,四边形都具有完全相同的外观。即使我将 alpha 设置为 0.0,它也会以纯红色绘制。

我打开了 GL_BLEND。这是我的初始化:

GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);        
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
GLES20.glDisable(GLES20.GL_CULL_FACE);
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);

绘制函数非常简单:

GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
shader.use(); // will select the vertex and fragment shader
GLES20.glViewport(0, 0, resX, resY); // sets the viewport to the current resolution
GLES20.glEnableVertexAttribArray(v_aPosId);
GLES20.glVertexAttribPointer(v_aPosId, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
0, vertexBuf);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertexCount);
GLES20.glDisableVertexAttribArray(v_aPosId);

表面 View 的创建方式如下:

glView = new GLSurfaceView(this);
glView.setEGLContextClientVersion(2);
glView.setRenderer(new GLRenderer(this));

为什么 Alpha channel 会被忽略?我是否错过了打开或关闭某些东西?使用的硬件:搭载 Android 4.2.1 的 Google Nexus 10。

编辑:当我使用 glReadPixels() 读回帧缓冲区时,RGBA 像素值也是 255, 0, 0, 255 >,而不是应有的 255, 0, 0, 127。不过我修好了。如果您想正确显示透明度,请参阅@martijn-courteaux的答案。如果您想获取正确的像素值(如通过 glReadPixels()),请参阅我的答案。

最佳答案

选择glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);混合函数时,您必须预乘颜色。因此,这意味着您必须将每个颜色分量(红色、绿色和蓝色)乘以 alpha 值。在您的情况下,这将是:(1.0 * alpha, 0.0, 0.0, alpha)。混合函数描述了 GPU 如何计算两种混合颜色的最终颜色。如果您选择 GL_ONE、GL_ONE_MINUS_SRC_ALPHA,则会得到以下公式:

finalColor = srcColor + (1 - srcAlpha) * dstColor;

如果您填写红色,您会看到:

finalColor = (1.0, 0.0, 0.0) + (1 - 0.5) * (0.0, 0.0, 0.0)
= (1.0, 0.0, 0.0)

这就是为什么它看起来是纯红色的。

如果您不喜欢这样,请将混合功能更改为:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);如果使用这个函数,公式就很明显了:

finalColor = srcAlpha * srcColor + (1 - srcAlpha) * dstColor;

插入红色:

finalColor = 0.5 * (1.0, 0.0, 0.0) + (1.0 - 0.5) * (0.0, 0.0, 0.0)
= (0.5, 0.0, 0.0)

请注意,当您处理图像时,预乘很有用:它可以为每个 fragment 节省 GPU 三次乘法。

关于java - OpenGL ES 2.0 : Alpha value in fragment shader is ignored (using glReadPixels()),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20254811/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com