nishant
nishant

Reputation: 756

GLKit does not display texture when using GL_MODULATE with alpha in vertex color

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:


Original Texture This is the original texture


RGBA (1.0, 1.0, 1.0, 1.0) 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) 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) RGBA (1.0, 0, 0, 1.0) - red color , no premultiplication, opaque, texture visible


RGBA (1.0, 0, 0, 0.5) RGBA (1.0, 0, 0, 0.5) - red color, no premultiplication, alpha = 0.5, texture lost


RGBA (0.5, 0, 0, 0.5) - after premutiplying a = 0.5 per @andon 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) - after premutiplying a = 0.5 per @andon 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) - after premutiplying a = 0.5 per @andon 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

Answers (1)

Andon M. Coleman
Andon M. Coleman

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.

You can see why below:

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).

Proper blending should look like this:

// 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.

Correct pre-multiplied alpha blending (by pre-multiplying vertex color):

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

Related Questions