Masked Texture from image

Blitz3D Forums/Blitz3D Programming/Masked Texture from image

KronosUK(Posted 2014) [#1]
I'm trying to create a masked texture from an image however the mask flag on the texture seems to have no effect. Should this work or am I doing something wrong?




RGR(Posted 2014) [#2]
http://www.blitzbasic.com/b3ddocs/command.php?name=CreateTexture&ref=comments


Rick Nasher(Posted 2014) [#3]
What exactly isn't working? Do you mean if you try to apply to an entity it's not taking it? Does it have prebaked textures as in a B3D file?

If so check these threads:
http://www.blitzbasic.com/Community/posts.php?topic=102518

and:
http://www.blitzbasic.com/Community/posts.php?topic=102163

Flag 4 using tga for masked textures somehow worked better for me too.


Kryzon(Posted 2014) [#4]
It's not working because it needs to be processed in a certain way, and Blitz3D only preprocesses masked textures like that when you load them with LoadTexture(). It doesn't process textures that you manually create.
The masked effect is really 'alpha-testing,' the technique used in masking: rasterized pixels of a mesh that have an alpha value below a threshold (usually 0.5) are discarded from rendering, and each pixel has their alpha values as the combination of the vertex colours, material colour and texture sampling.

The Blitz3D documentation says that the masking is based on the black colour, but internally it's really based on alpha values - at the moment of loading your masked texture, Blitz3D writes on the masked texture an alpha value of zero for all the black texels, and an alpha value of 1.0 for all the other texels.
This can be confirmed through experimentation.

So if you want a texture that you created yourself to have the masked effect working properly, you need to manually implement that same preprocessing that Blitz3D does.

Function MaskTexture( texture%, maskR% = 0, maskG% = 0, maskB% = 0 )

	Local w = TextureWidth( texture ) - 1
	Local h = TextureHeight( texture ) - 1

	Local sampleRGB
	Local maskRGB = ( maskR Shl 16 ) + ( maskG Shl 8 ) + maskB

	LockBuffer( TextureBuffer( texture ) )

		For y = 0 To h

			For x = 0 To w
			
				sampleRGB = ReadPixelFast( x, y ) And $00FFFFFF ;Sample from the texture, reset the sampled alpha value.
			
				If sampleRGB = maskRGB Then 

					;The texel should be masked.
				
					WritePixelFast( x, y, sampleRGB )

				Else

					;The texel is visible. Set a maximum alpha value.

					WritePixelFast( x, y, sampleRGB Or $FF000000 ) ;

				EndIf
	
			Next

		Next

	UnlockBuffer( TextureBuffer( texture ) )

End Function
Const FLAG_COLOUR = 1
Const FLAG_MASKED = 4

Local myTexture = CreateTexture( ..., FLAG_COLOUR + FLAG_MASKED )

CopyRect( ... ) ;Fill the texture with content.

MaskTexture( myTexture, 255, 0, 255 ) ;Mask with magenta colour, for example.



KronosUK(Posted 2014) [#5]
Thanks for the explanation Kryzon I have it working now.