[英]iOs OpenGL ES 2.0 blending with shader on device and on simulator
[英]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.