Reputation: 756
I have a texture image that I am using with GLKit. If I use GL_MODULATE on the texture and have vertex RGBA (1.0, 1.0, 1.0, 1.0) then the texture shows up entirely as it would do in GL_REPLACE. Fully opaque.
Then if I use Red (1.0, 0.0, 0.0, 1.0) for vertex RGB the texture shows up again as Red modulating the texture.
So far so good.
But when I change the transparency in the vertex color and I use RGBA(1.0, 0.0, 0.0, 0.5), then only a light red color is seen and the texture is not visible, so the color is replacing the texture entirely.
The texture itself has no alpha, it is RGB565 texture.
I am using GLKit with GLKTextureEnvModeModulate.
self.effect.texture2d0.envMode = GLKTextureEnvModeModulate;
Any help on why the texture would disappear, when I specify the alpha?
Adding snapshots:
This is the original texture
RGBA (1.0, 1.0, 1.0, 1.0) - white color , no premultiplication, opaque, texture visible
RGBA (1.0, 1.0, 1.0, 0.5) - white color, no premultiplication, alpha = 0.5, texture lost
RGBA (1.0, 0, 0, 1.0) - red color , no premultiplication, opaque, texture visible
RGBA (1.0, 0, 0, 0.5) - red color, no premultiplication, alpha = 0.5, texture lost
RGBA (0.5, 0, 0, 0.5) - red color, premultiplication, alpha = 0.5 per @andon, texture visible, but you may need to magnify to see it
RGBA (0.1, 0, 0, 0.1) - red color, premultiplication, alpha = 0.1 per @andon, texture lost, probably because not enough contrast is there
RGBA (0.9, 0, 0, 0.9) - red color, premultiplication, alpha = 0.9 per @andon, texture visible, but you may need to magnify to see it
Upvotes: 1
Views: 195
Reputation: 43389
The texture itself has no alpha, it is RGB565 texture
RGB565
implicitly has constant alpha (opaque -> 1.0). That may not sound important, but modulating vertex color with texture color does a component-wise multiplication and that would not work at all if alpha were not 1.0.
My blend function is for pre-multiplied - One, One - Src.
This necessitates pre-multiplying the RGB components of vertex color by the A component. All colors must be pre-multiplied, this includes texels and vertex colors.
Vtx = (1.0, 0.0, 0.0, 0.5)
Tex = (R, G, B, 1.0)
// Modulate Vertex and Tex
Src = Vtx * Tex = (R, 0, 0, 0.5)
// Pre-multiplied Alpha Blending (done incorrectly)
Blend_RGB = Src * 1 + (1 - Src.a) * Dst
= Src + Dst / 2.0
= (R, 0, 0) + Dst / 2.0
The only thing this does is divide the destination color by 2 and add the unaltered source color to it. It is supposed to resemble linear interpolation (a * c + (1 - c) * b
).
// Traditional Blending
Blend_RGB = Src * Src.a + (1 - Src.a) * Dst
= (0.5R, 0, 0) + Dst / 2.0
This can be accomplished using the original blend function if you multiply the RGB part of the vertex color by A.
Vtx = (0.5, 0.0, 0.0, 0.5) // Pre-multiply: RGB *= A
Tex = (R, G, B, 1.0)
// Modulate Vertex and Tex
Src = Vtx * Tex = (0.5R, 0, 0, 0.5)
// Pre-multiplied Alpha Blending (done correctly)
Blend_RGB = Src * 1 + (1 - Src.a) * Dst
= (0.5R, 0, 0) + Dst / 2.0
Upvotes: 2