当我将它们与OpenGL混合时,文本周围会有灰色阴影。
当前,这是我的混合功能:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
如果我将其更改为:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
它起作用了,我用Gimp获得了相同的结果:
但是,但是使用GL_ONE时,文本不能再淡入背景。就像透明度0或1。
同样使用GL_ONE,两张图片之间的淡入淡出将以某种方式使结果图像超亮:
使用GL_SRC_ALPHA看起来很正常:
因此,这两种解决方案都各有利弊。我不需要灰色阴影,但我想保持交叉淡入淡出效果。任何建议都将不胜感激。
这是我的片段着色器:
gl_FragColor = (v_Color * texture2D(u_Texture, v_TexCoordinate));
以下是纹理(文本和图像)的加载方式(最后预乘):
+ (GLuint)getGLTextureFromCGIImage:(CGImageRef)cgiImage {
size_t width = CGImageGetWidth(cgiImage);
size_t height = CGImageGetHeight(cgiImage);
GLubyte *spriteData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef spriteContext = CGBitmapContextCreate(spriteData,
width,
height,
bitsPerComponent,
bytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), cgiImage);
CGContextRelease(spriteContext);
return [GLMediaUtils getGLTextureFromPixelsInFormat:GL_RGBA
width:(int)width
height:(int)height
pixels:spriteData];
}
+ (GLuint)getGLTextureFromPixelsInFormat:(GLenum)format
width:(int)width
height:(int)height
pixels:(void *)pixels {
glActiveTexture(GL_TEXTURE0);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GLenum type = GL_UNSIGNED_BYTE;
if(format == GL_RGB) // RGB565
type = GL_UNSIGNED_SHORT_5_6_5;
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, pixels);
free(pixels);
glFlush();
return texture;
}
答案 0 :(得分:1)
您快到了。如果要避免从纹理重影,则需要使用预乘Alpha(因为GL混合通常是后乘Alpha,这会导致通道中的颜色泛滥)。
通常GL_ONE
起作用是因为在纹理上传之前,正确的alpha已被预先烘焙到RGB颜色通道中。如果您开始在着色器中添加自定义淡入淡出,那么最终会导致在着色器中用于混合的Alpha与用于预乘的Alpha之间不同步。
...因此您需要根据新的alpha值向片段着色器添加调整,以返回到稳定的预乘值。像这样:
vec4 texColor = texture2D(u_Texture, v_TexCoordinate);
// Scale the texture RGB by the vertex color
texColor.rgb *= v_color.rgb;
// Scale the texture RGBA by the vertex alpha to reinstate premultiplication
gl_FragColor = texColor * v_color.a;
另一种方法是将字体仅存储为亮度纹理。您会得到灰色阴影,因为颜色通道在字体之外为黑色,并且纹理过滤将白色和黑色混合在一起。如果您知道字体颜色是白色,则根本不需要在纹理中存储RGB
值...(或者,如果您很懒,只需保留现有纹理并用白色填充整个纹理RGB通道即可。 )。