簡體   English   中英

OpenGL ES 2.0-文本混合問題(iOS)

[英]OpenGL ES 2.0 - Blending issue with text (iOS)

當我將它們與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;
} 

你快到了。 如果要避免從紋理重影,則需要使用預乘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通道即可)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM