Per-Pixel Texture Alpha?
Blitz3D Forums/Blitz3D Programming/Per-Pixel Texture Alpha?
| ||
Is it possible to apply "true" per-pixel alpha to a texture in code? I can apply the alpha to the texture okay (after the texture's been applied to the entity and using WritePixelFast(X, Y, (Alpha Shl 24) Or RGB, TextureBuffer) ) but it doesn't seem to be applied properly. Any pixels with alpha 128 or less are not rendered, while any pixels with alpha 129 or more are rendered fully opaque. I've tried all sort of combinations of EntityBlend, EntityFX and TextureBlend, but most of those just make it worse :-) Is this actually possible? |
| ||
LoadTexture() with a certain texture flags. (I think 4.) Download TGATool to make textures with alpha channels: www.leadwerks.com |
| ||
I'm having to do it in code 'cos I'm building the texture at runtime. |
| ||
Your texture seems to be using masking, instead of alpha. When you create the texture, make sure you use the alpha flag. Texture masking works on the basis of the number being above 128 being poaque and less then being transparent, as you have found out. But, probably because you are using the mask flag, instead of the alpha flag. |
| ||
I'm pretty sure I'm passing the correct flag into the routine that creates the texture but I'm not sure if I've ever actually traced it through to make sure it gets to the CreateTexture properly. Thanks - I'll check it out. |
| ||
Halo - 4?!? WTH! Must be Alz..thingy... It's t=createtexture(width, height, 2) and if you have multiple texture layers, you may get troubles, depending on the blending modes of the other layers. AND: if you read RGB, make sure to mask it with $FFFFFF to make sure its alpha byte won't deliver random bits. |
| ||
I'd forgotten to mask the read pixel with $00ffffff, which is particularly daft as I knew I had to do it. Thanks guys, all working now :-) |
| ||
could someone post a working example of this code cos i've been trying to create textures with the alpha working.thnx |
| ||
What I did was either load or create your texture with TextureFlags = 2 I get the texture from an entity with: Local Brush = GetEntityBrush(Entity) Local Texture = GetBrushTexture(Brush)Then I use ApplyAlphaToTexture (below) to apply alpha to the texture (very roughly) according to brightness: Function ApplyAlphaToTexture(Texture) Local tw = TextureWidth(Texture) Local th = TextureHeight(Texture) Local tb=TextureBuffer(Texture) LockBuffer(tb) Local x,y For x=0 To tw-1 For y=0 To th-1 Local RGB = ReadPixelFast(x,y,tb) And $00ffffff Local Red = GetRedFromRGB(RGB) Local Green = GetGreenFromRGB(RGB) Local Blue = GetBlueFromRGB(RGB) ; Calculate the alpha (very roughly) according to the brightness of the pixel Local Alpha = (Red + Green + Blue) / 3 WritePixelFast(x, y, (Alpha Shl 24) Or RGB, tb) Next Next UnlockBuffer tb End Function Function GetRedFromRGB(RGB) Return RGB / (256 * 256) + 256 End Function Function GetGreenFromRGB(RGB) Return (RGB Mod (256 * 256)) / 256 + 256 End Function Function GetBlueFromRGB(RGB) Return (RGB Mod (256 * 256)) Mod 256 + 256 End FunctionHope that helps. |
| ||
BTW: Local Brush = GetEntityBrush(Entity) will create a copy of the original brush, so you have to delete it when it isn't used anymore. |
| ||
Yes, very true jfk :-) I've hit a snag though. The following code (slightly different from what I posted above) works fine on one PC (with Geforce 4 gfx), but on another (with Intel gfx) the ReadPixelFast returns $0000FFFF for pixels that are quite clearly black (should be $00000000). In fact, for all pixels the Green and Blue are always $FF. Anyone got any ideas why this might happen? Local TexBuff = TextureBuffer(Texture) LockBuffer(TexBuff) For X = 0 To TextureWidth(Texture) -1 For Y = 0 To TextureHeight(Texture) -1 Local RGB = ReadPixelFast(X, Y, TexBuff) And $00ffffff Local Red = (RGB Shr 16) And $ff Local Green = (RGB Shr 8) And $ff Local Blue = RGB And $ff Local Alpha = (Red + Green + Blue) / 3 DebugLog (Hex(RGB) + " > " + Red + ", " + Green + ", " + Blue + " = " + Alpha) WritePixelFast(X, Y, (Alpha Shl 24) Or RGB, TexBuff) Next Next UnlockBuffer(TexBuff) |
| ||
More info: whatever I And the readpixel with, the last 2 bytes of the resulting value are the same as the last 2 bytes of the And value. So if I And it with $00123456 I get $00003456. It looks to my (inexpert) eye like ReadPixelFast is only returing 2 bytes. This is all in 32-bit mode btw. |
| ||
Actually I realised in the shower this morning that if the readpixel returns $0000FFFF then of course the last 2 bytes will equal the mask. So, erm, ignore the post above :-) The problem (black pixels returning $0000FFFF) still remains though. |