I have a sheet of black shapes surrounded by transparency. I have successfully loaded this texture with GLKit and I can draw the shapes using GLKBaseEffect into rectangles. Is there a way to change the color of the black (ie non-transparent) pixels, so I can draw yellow shapes or blue shapes etc? Or do I need a custom shader to do this?
2 Answers
It seems like you'll need a custom shader (which I highly recommend working with) as you need to check individual texel color values, but here are some suggestions to try first:
You can pass color as per-vertex data in a vertex attribute array pointing to GLKVertexAttribColor. This will allow you to individually set the color of each vertex (and ultimately, faces) but it will be difficult to see where they line up against your texture.
You can try enabling the following property on your effect:
effect.colorMaterialEnabled = YES;
But, for both cases, if your texels are completely black then I don't think any changes in color will show.
I think a custom shader is definitely the way to go, as you'll need to do something like this:
highp vec4 finalColor;
highp vec4 textureColor = texture2D(uTexture, vTexel);
highp vec4 surfaceColor = uColor;
// If texel is non-transparent (check alpha channel)
if(textureColor.a > 0.001)
finalColor = surfaceColor;
else
finalColor = vec4(0.0, 0.0, 0.0, 0.0);
gl_FragColor = finalColor;
Where anything prefixed with u is a uniform variable passed into the shader.
To get fully colorized textures, use:
self.effect.texture2d0.envMode = GLKTextureEnvModeModulate;
Which tells OpenGL to take whatever color is in your texture and multiply it by whatever color the underlying geometry is. You can then use vertex coloring to get neat fades and whatnot.
NOTE: You'll want to change your texture from black to white (1, 1, 1, 1), so multiplication works correctly.
NOTE: Here are some other settings that you should already have in place:
self.effect.texture2d0.enabled = GL_TRUE;
self.effect.texture2d0.target = GLKTextureTarget2D;
self.effect.texture2d0.name = self.texture.name;
self.effect.colorMaterialEnabled = GL_TRUE;
NOTE: You can experiment with GLKTextureEnvModeDecal
, too, which blends your texture on top of colored geometry (as when applying a decal), so the transparent parts of the texture show the geometry underneath.