Alpha Sprite Problem

BlitzMax Forums/MiniB3D Module/Alpha Sprite Problem

siread(Posted 2010) [#1]
I noticed a problem when loading a sprite with alpha transparency. As you can see some trees appear behind the fence.



This is the same sprite only loaded as masked. I don't see any problems with masked sprites.



I would prefer to use alpha sprites because they look a lot nicer and allows me to fake an transparent shadow at the bottom. Any idea what the problem is?

Also, will I suffer a big performance hit with alpha sprites?


ima747(Posted 2010) [#2]
I've been trying to trackdown this and other related alpha sprite issues for a while. Try setting the alpha on the sprites to 0.99 instead of 1.0 this sometimes fixes problems and sometimes causes z buffer issues...


siread(Posted 2010) [#3]
Setting EntityAlpha to 0.99 had no effect. :(


SLotman(Posted 2010) [#4]
I tought miniB3D did ordered the alpha'ed sprites, unlike Blitz3D, but apparentely not?

This is the same problem that happens on Blitz3D: sprites and every mesh with alpha should be z-ordered accordingly to their distance to the camera - or this will happen, no matter what.

Every 3D engine out there, that doesn't sort alpha, have this kind of problem, so it's not unique to B3D or miniB3D... but sure would be nice to have it.

Again, I tought mini3D did the z-sorting thing... please someone correct me if I'm wrong.


_Skully(Posted 2010) [#5]
Correct


siread(Posted 2010) [#6]
Each straight peice of fencing is a simple 2 triangle mesh (with backface culling turned off). The Z position of the fence in this image lies somewhere near the red dot. As you can see, the trees behind this point on the z-plane are being drawn behind the fence. Strange that the masked sprites work fine.




SLotman(Posted 2010) [#7]
bad info... just ignore this post ;)


SLotman(Posted 2010) [#8]
and another post to be ignored :)


SLotman(Posted 2010) [#9]
Scratch all that. MiniB3D does sort everything correctly.

By any chance are you exporting all meshes into a single one?
Because if geometry are created 'on world position' (ex: the position is encoded on vertex data) - then you've got a problem.

miniB3D uses entityX/Y/Z to calculate the distance from objects to camera. If they're all a single mesh, they are all returning the same position (0,0,0) - and so, they aren't being properly sorted.

create your models at 0,0,0 - and then do a positionentity to their real position. This should solve the alpha rendering problems.


siread(Posted 2010) [#10]
Each wall is an individual mesh. I create them at 0,0,0 then scale, rotate and position them.

The wall data is stored simply as a list of x,y co-ordinates. "lastpoint" refers to the end point of the last wall (and therefore the startpoint of the new wall) whilst "wp" is the end point of the new wall.
				Local length:Float = GetDistance(lastpoint.x, lastpoint.y, wp.x, wp.y)				
				Local wallmesh:TMesh = CreateMesh()
				Local s:TSurface=CreateSurface(wallmesh)
				AddVertex s,-1,+1,-1,0,0
				AddVertex s,+1,+1,-1,1,0
				AddVertex s,+1,-1,-1,1,1
				AddVertex s,-1,-1,-1,0,1
				AddTriangle s,0,1,2
				AddTriangle s,0,2,3
				
				ScaleMesh(wallmesh, (length/2), 10, 0)
				PositionEntity(wallmesh, (lastpoint.x + wp.x) /2, 10, -((lastpoint.y + wp.y)/2))
				RotateEntity(wallmesh, 0, -GetDirection(lastpoint.x, lastpoint.y, wp.x, wp.y), 0)
				

The fact that the masked sprites work ok suggests it's a bug in miniB3D though, right?


ima747(Posted 2010) [#11]
minib3d does Z order alpha entities, or atleast it tries to. if you vary the alpha you will get different results. it also depends on how much overlap the alpha object has with something else (e.g. if the alpha object is directly in line with the other object's center it usually works fine, if it's out of line and slides over it will be behind until there is enough overlap and it pops on top.) this largely seems to happen all based on ranges. if you move the alpha item farther from the object behind it it tends to have fewer problems.

I've been struggling with this for a while without much success.

http://blitzmax.com/Community/posts.php?topic=86899 2nd post

Interesting about the masked sprites drawing correctly, as if I remember correctly they get tagged as alpha and should be rendered with the same Z ordering used for regular sprites... I'm going to have a rummage.


ima747(Posted 2010) [#12]
I think the problem comes from center distances...

Alpha entities are ordered (assuming entityorder of 0, normal) based on Entity.EntityDistanceSquared(Camera). this goes from the center points of all entities to the center point of the camera. So if something's center point is closer than another object's but it's left side is further away, it's left side will still be drawn on top of the other object.

I still don't know why the masked sprites work though, that gives me hope.


SLotman(Posted 2010) [#13]

Alpha entities are ordered (assuming entityorder of 0, normal) based on Entity.EntityDistanceSquared(Camera). this goes from the center points of all entities to the center point of the camera. So if something's center point is closer than another object's but it's left side is further away, it's left side will still be drawn on top of the other object.



That's the correct (and fast) way to do it!

I still don't know why the masked sprites work though, that gives me hope.

Because they don't use alpha - so the hardware sort them without problems.


The wall data is stored simply as a list of x,y co-ordinates. "lastpoint" refers to the end point of the last wall (and therefore the startpoint of the new wall) whilst "wp" is the end point of the new wall.


Are the trees created in the same manner? If so, it could be another issue with texture flags that I comment below...


The fact that the masked sprites work ok suggests it's a bug in miniB3D though, right?

Nope, every 3d engine that doesn't sort objects with alpha does that - it's a hardware problem - no graphics card can render them in the correct order (something to do with zbuffer getting lost during rasterization)

This is the test I did here (code adapted from Blitz3D), and it works:


Make sure your texture is loaded if alpha flag 2 or 3, because minib3D looks exactly for those.

On TMesh.bmx, on the alpha function you see this:
If brush.alpha#<1.0 Or brush.blend = 2 Or brush.blend=3 Or brush.fx&32


I changed to this:
If brush.alpha#<1.0 Or brush.blend&2 Or brush.fx&32


See if that solves your problem...


ima747(Posted 2010) [#14]
I still don't know why the masked sprites work though, that gives me hope.

Because they don't use alpha - so the hardware sort them without problems.


Been looking a little deeper here. All textures are converted to RGBA8888 when they are made. So technically they all have alpha, though they may not be drawn with it enabled (i.e. Z ordered). Masked images just have MaskPixmap() applied to the texture pixmap. So they are drawn normally (no Z ordering), but MaskPixmap just sets the alpha of the masked pixels to 0... so they do use the alpha channel on the texture's pixmap for masking they just have values of 1 or 0... so normal texture drawing supports alpha 0, and you only need z ordering when alpha blending is being applied and alpha > 0 and < 1?


simonh(Posted 2010) [#15]
Slotwise is correct, masked sprites aren't really alpha sprites, just normal meshes with bits missing. As for your fix slotman, don't think that will work as brush blend doesn't use bitwise flags.


SLotman(Posted 2010) [#16]
So how should one check for a mesh with textured alpha, so the "mesh.alpha" returns true?


simonh(Posted 2010) [#17]
That's what texture flag 2 is for, to indicate the texture has alpha.


siread(Posted 2010) [#18]
So I've tried working with masked textures only but this causes other issues. As you can see in the pic, the fence texture is more jaggedy than before, but worse still is that as it stretches into the distance it disappears very quickly...



Any suggestions on the best way forward? What alternatives are there? Thanks.


SLotman(Posted 2010) [#19]
It should work with alpha... how big are your meshes? this wall is just a pair of triangles stretched to it's whole size? That would explain the errors, miniB3D would get only the mesh center as a reference on the z-sorting.

This could explain why some trees, in diagonal are being rendered below the fence... their 'center' is further away from the camera than the 'wall center', so it's rendered first.

If it's not... I have no clue, sorry :(


Kryzon(Posted 2010) [#20]
My guess is that that texture has a low resolution, and therefore the sampler tends to pick more masked texels than visible ones the farther away from the camera the fragments get. Are you absolutely sure you have MipMapping turned on for that texture? it's very jagged.

You could try using a higher resolution texture for that fence, or thicken the visible parts a bit.

EDIT: I just noticed some of the trees' logs are invisible. Was that on purpose?


Leon Drake(Posted 2010) [#21]
maybe it's because Master Blaster runs Barter Town


Kryzon(Posted 2010) [#22]
I didn't get what you said, but that didn't stop me from laughing at it.


Hotshot2005(Posted 2010) [#23]
Hey siread

Grand prix game is one I am looking forward to :)

I have play your demo as tennis,new stars fooball but the one i keep playing was Dart game where I had 9 Darter! Ace game that was! :)


Tom(Posted 2010) [#24]
siread: Looks like a texture filter thing.

Using Peters small fixes version

Load up TMesh.bmx, around about line 1800

' mipmapping texture flag
If tex_flags&8<>0
....
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR)

Try changing the last parameter to one of the following, see if it makes a difference.

GL_NEAREST_MIPMAP_NEAREST
GL_LINEAR_MIPMAP_NEAREST
GL_NEAREST_MIPMAP_LINEAR *default in minib3d
GL_LINEAR_MIPMAP_LINEAR
GL_NEAREST
GL_LINEAR

You will need to load the texture with the mipmap flag.

If it doesn't improve things change it back to the default.


siread(Posted 2010) [#25]
Wow. Using Peters version fixed the trees displaying behind fences straight away so I can use alpha textures again. :D

Thanks for suggesting that Tom, and cheers to Peter of course.


simonh(Posted 2010) [#26]
I don't think Peter's small fix version fixes anything that relates to alpha sorting, although I may be wrong. Be aware that you may occasionally get lucky with alpha sorting - things appearing in the right order when on other occasion they might not.