问题:当图像在此相机上显示并包含发光效果时,它会变黑
issue: when an image is displayed on this camera and contains a glow effect, it becomes black
已解决。请看下面我的回答。
---------------------------
编辑 3:
差不多解决了。请按最后一次。
我尝试了 Rabbid76 建议的比例和 modulateGlow,蝴蝶是透明的。请看椅子上的蝴蝶和地上的大蝴蝶
这是原始图像(其中之一):
--------------------------
编辑 2:
多亏了Rabbid76,差不多解决了!
左图显示了使用 Rabbid76 解决方案的当前结果。右图显示了预期的解决方案。如你所见,蝴蝶现在变成了lighter\transparent。
---------------------------
编辑 1:
我尝试添加建议的 glBlendFunc,但它没有帮助,尽管它稍微影响了发光效果。我需要添加 GLES20.glEnable(GLES20.GL_BLEND) 因为默认情况下它是禁用的。
---------------------------
我正在使用这个存储库
https://github.com/MasayukiSuda/GPUVideo-android
它包含可以在相机上显示的滤镜。其中一个过滤器名为“WATERMARK”。当我把这张图片改成有发光效果的图片时,发光就变成了黑色。
图像位于:GPUVideo-android-master\sample\src\main\res\drawable-nodpi\sample_bitmap.png。为了触发问题,应该将其更改为具有发光效果的图像。例如我生成了这张图片:https://drive.google.com/file/d/1u8PtIftovPbXRLnI3OR9_1Kv37L5s96_/view?usp=sharing
您可以看到白色发光效果变成黑色的问题:
只需 运行 应用程序,点击“相机记录”,然后选择“人像”,然后从左侧列表中选择“WATERMARK”(倒数第 5 个)。不要忘记更改我提到的图像。
相关的class被命名为:GlWatermarkFilter。它扩展了包含下一个着色器的 GlOverlayFilter:
private final static String FRAGMENT_SHADER =
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform lowp sampler2D sTexture;\n" +
"uniform lowp sampler2D oTexture;\n" +
"void main() {\n" +
" lowp vec4 textureColor = texture2D(sTexture, vTextureCoord);\n" +
" lowp vec4 textureColor2 = texture2D(oTexture, vTextureCoord);\n" +
" \n" +
" gl_FragColor = mix(textureColor, textureColor2, textureColor2.a);\n" +
"}\n";
并且这个 class 也包含这个设置:
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
这个 class 扩展了 GlFilter,其中包含:
protected static final String DEFAULT_VERTEX_SHADER =
"attribute highp vec4 aPosition;\n" +
"attribute highp vec4 aTextureCoord;\n" +
"varying highp vec2 vTextureCoord;\n" +
"void main() {\n" +
"gl_Position = aPosition;\n" +
"vTextureCoord = aTextureCoord.xy;\n" +
"}\n";
protected static final String DEFAULT_FRAGMENT_SHADER =
"precision mediump float;\n" +
"varying highp vec2 vTextureCoord;\n" +
"uniform lowp sampler2D sTexture;\n" +
"void main() {\n" +
"gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
"}\n";
请帮我弄清楚如何修复它。我知道这是关于 semi-alpha 问题的,而这台相机不知道要显示它。我的目标是用发光的蝴蝶录制视频。
最有可能的是,发光效果纹理的颜色通道在发光区域的边缘逐渐淡出。这意味着发光区域边缘的纹理颜色通道具有从白色到黑色的渐变。如果是这种情况,则说明您错误地混合了纹理。您需要将发光效果 (textureColor2) 添加到基础纹理 (textureColor
):
gl_FragColor = textureColor + textureColor2;
一个选项是通过它的 alpha 通道缩放发光效果纹理
gl_FragColor = textureColor + textureColor2 * textureColor2.a;
如果发光效果看起来太亮,您可以通过缩放发光纹理来降低发光效果:
float scale = 0.5;
gl_FragColor = textureColor + textureColor2 * scale;
或者你可以通过颜色纹理来调制发光效果:
vec4 modulateGlow = textureColor2 * textureColor;
gl_FragColor = textureColor + modulateGlow;
这解决了所有问题,所以请注意最后两行:
private final static String FRAGMENT_SHADER =
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform lowp sampler2D sTexture;\n" +
"uniform lowp sampler2D oTexture;\n" +
"void main() {\n" +
" lowp vec4 textureColor = texture2D(sTexture, vTextureCoord);\n" +
" lowp vec4 textureColor2 = texture2D(oTexture, vTextureCoord);\n" +
" lowp float alphaDivisor = textureColor2.a + step(textureColor2.a, 0.0);\n" +
" gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb / alphaDivisor, textureColor2.a), textureColor.a);\n" +
"}\n";
已解决。请看下面我的回答。
---------------------------
编辑 3:
差不多解决了。请按最后一次。 我尝试了 Rabbid76 建议的比例和 modulateGlow,蝴蝶是透明的。请看椅子上的蝴蝶和地上的大蝴蝶
这是原始图像(其中之一):
编辑 2:
多亏了Rabbid76,差不多解决了! 左图显示了使用 Rabbid76 解决方案的当前结果。右图显示了预期的解决方案。如你所见,蝴蝶现在变成了lighter\transparent。
---------------------------
编辑 1:
我尝试添加建议的 glBlendFunc,但它没有帮助,尽管它稍微影响了发光效果。我需要添加 GLES20.glEnable(GLES20.GL_BLEND) 因为默认情况下它是禁用的。
---------------------------
我正在使用这个存储库
https://github.com/MasayukiSuda/GPUVideo-android
它包含可以在相机上显示的滤镜。其中一个过滤器名为“WATERMARK”。当我把这张图片改成有发光效果的图片时,发光就变成了黑色。
图像位于:GPUVideo-android-master\sample\src\main\res\drawable-nodpi\sample_bitmap.png。为了触发问题,应该将其更改为具有发光效果的图像。例如我生成了这张图片:https://drive.google.com/file/d/1u8PtIftovPbXRLnI3OR9_1Kv37L5s96_/view?usp=sharing
您可以看到白色发光效果变成黑色的问题:
只需 运行 应用程序,点击“相机记录”,然后选择“人像”,然后从左侧列表中选择“WATERMARK”(倒数第 5 个)。不要忘记更改我提到的图像。
相关的class被命名为:GlWatermarkFilter。它扩展了包含下一个着色器的 GlOverlayFilter:
private final static String FRAGMENT_SHADER =
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform lowp sampler2D sTexture;\n" +
"uniform lowp sampler2D oTexture;\n" +
"void main() {\n" +
" lowp vec4 textureColor = texture2D(sTexture, vTextureCoord);\n" +
" lowp vec4 textureColor2 = texture2D(oTexture, vTextureCoord);\n" +
" \n" +
" gl_FragColor = mix(textureColor, textureColor2, textureColor2.a);\n" +
"}\n";
并且这个 class 也包含这个设置:
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
这个 class 扩展了 GlFilter,其中包含:
protected static final String DEFAULT_VERTEX_SHADER =
"attribute highp vec4 aPosition;\n" +
"attribute highp vec4 aTextureCoord;\n" +
"varying highp vec2 vTextureCoord;\n" +
"void main() {\n" +
"gl_Position = aPosition;\n" +
"vTextureCoord = aTextureCoord.xy;\n" +
"}\n";
protected static final String DEFAULT_FRAGMENT_SHADER =
"precision mediump float;\n" +
"varying highp vec2 vTextureCoord;\n" +
"uniform lowp sampler2D sTexture;\n" +
"void main() {\n" +
"gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
"}\n";
请帮我弄清楚如何修复它。我知道这是关于 semi-alpha 问题的,而这台相机不知道要显示它。我的目标是用发光的蝴蝶录制视频。
最有可能的是,发光效果纹理的颜色通道在发光区域的边缘逐渐淡出。这意味着发光区域边缘的纹理颜色通道具有从白色到黑色的渐变。如果是这种情况,则说明您错误地混合了纹理。您需要将发光效果 (textureColor2) 添加到基础纹理 (textureColor
):
gl_FragColor = textureColor + textureColor2;
一个选项是通过它的 alpha 通道缩放发光效果纹理
gl_FragColor = textureColor + textureColor2 * textureColor2.a;
如果发光效果看起来太亮,您可以通过缩放发光纹理来降低发光效果:
float scale = 0.5;
gl_FragColor = textureColor + textureColor2 * scale;
或者你可以通过颜色纹理来调制发光效果:
vec4 modulateGlow = textureColor2 * textureColor;
gl_FragColor = textureColor + modulateGlow;
这解决了所有问题,所以请注意最后两行:
private final static String FRAGMENT_SHADER =
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform lowp sampler2D sTexture;\n" +
"uniform lowp sampler2D oTexture;\n" +
"void main() {\n" +
" lowp vec4 textureColor = texture2D(sTexture, vTextureCoord);\n" +
" lowp vec4 textureColor2 = texture2D(oTexture, vTextureCoord);\n" +
" lowp float alphaDivisor = textureColor2.a + step(textureColor2.a, 0.0);\n" +
" gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb / alphaDivisor, textureColor2.a), textureColor.a);\n" +
"}\n";