Billboard overlap problem, text gets behind speechbubble :/

Hi!

Im making a speech bubble for my people so that cops can shout at robbers and engage in battle :stuck_out_tongue:



Anyway, heres a screenshot of the 3 diffrent senarios that happens with the speechbubble:

http://i.imgur.com/8wSj3.png

And heres the code:

[java]public class ChatBubble {



public ChatBubble(Node piv, String msg, boolean shout) {

BillboardControl bc = new BillboardControl();

bc.setAlignment(BillboardControl.Alignment.Screen);



String bubbleImage = “SpeechBubble.png”;

if (shout) {

bubbleImage = “ShoutBubble.png”;

}



Picture bubble = new Picture("");

bubble.setImage(MainClass.getAsset(), bubbleImage, true);

bubble.scale(2);





bubble.setIgnoreTransform(false);

bubble.setQueueBucket( Bucket.Transparent );

bubble.setPosition(-1, 0);



bubble.addControl(bc);

bubble.setLocalTranslation(0,2,0);

piv.attachChild(bubble);





BitmapFont fnt = MainClass.getAsset().loadFont(“Interface/Fonts/Default.fnt”);



BitmapText label = new BitmapText(fnt, false );

label.setSize( .3f );

label.setText(msg);



float textWidth = label.getLineWidth();

float textOffset = textWidth / 2;

label.setBox( new Rectangle(-textOffset,0, textWidth, label.getHeight()) );

label.setColor(ColorRGBA.Black);

label.setAlignment( BitmapFont.Align.Left);

label.setQueueBucket( Bucket.Transparent );





BillboardControl bc2 = new BillboardControl();

bc2.setAlignment(BillboardControl.Alignment.Screen);



label.addControl(bc2);

label.setLocalTranslation(0,4,0);

piv.attachChild(label);



}



}[/java]



Create a new instance of it will do the bubble.

But as you can see, they overlap diffrently depending on the angle your watching it from.

How can I manually adjust which to be renderd first?

What about just making it a boring old sprite instead? I haven’t messed around with the code (still doing the tutorials etc) but given that the cops and robbers I assume are AI controlled their vocabulary will be rather limited no? Unless, you know, you get their speeches from Twitter feeds or something… Which’d be hilarious I think.

Anything else that might help find the root of the problem? Like hints when the first two scenarios happen. That would help find the possible cause.

Yes, it is limited. But point of this game is to be as moddable as possible, as this “game” will only work as city engine.

So if you create a new “soul” you can choose just write in what you want it to say in certain situations. And I dont want to have to make a new image with text for every word some certain person would want to say, that is just waste of time.



Also another question (not that the first is solved but, ohwell :slight_smile: :

I want the image to be centerd just as the text is, how would I do that?

Ahh, didn’t see you’r comment madj.

There aren’t special senarios. I think this is what’s called z-fighting. Like placing 2 identical cubes at same place but with diffrent colors.

Who will overlap who changes constantly.

I know what Z-fighting is. :wink:



Right off the top of my head what I can suggest is to slightly move the X/Z coordinates of the text so it’s a bit in front on the bubble, at a quick glance from the posted code above, it seems like both the bubble and the text share the same X/Z, which might be why there’s some Z-fighting there. Maybe add something along the line of .05f…



Hopefully that’ll help.

  1. how to solve z-fighting.

    convert buble to BufferedImage and add the text there, create a texture afterwords. You will have to do this for every time you change the text.



    This also solves the positioning issues you have.

Didn’t seem to work…

I tried adjusting it’s z coords but it just made the error appear longer once they appeard.

There is not renderbucket or something simular that I should have a look at?

There are a few approaches. The simplest is probably to put them both together under one node and then billboard that node instead of each individually. Then you can adjust the position of one of them to be in front of the other. You may have to play with this as I’m not sure whether’s its x, y, or z that you need to adjust under a screen billboarded node.



That’s the simplest solution and will work as long as they are both the same size. Note that if they were at the same x,y,z location and one of them is larger then it will always be drawn last (transparent bucket draws back to front and bigger objects at the same location register as nearer). So you could leave them at the same location and make the bubble bigger than the text… which may ultimately be what you want to do anyway.



Another approach is to tap into the additional render state of the text’s material and give it a poly offset. You’ll want to clone and reset the BitmapText material so that you aren’t adjusting the poly offset for every text object… at least I think that works.



There is another way the is guaranteed to work but it’s the most complicated. You can actually directly control the sort order of the entire transparent bucket but it’s not for the faint of heart. Try everything else first.

Add: note that since these are flat the size thing probably won’t work on its own… you probably have to also adjust the locations to be slightly different than one another.

Also, maybe you can try this on the bubble material mat.getAdditionalRenderState().setPolyOffset(-1.0f,-1.0f);

this should push forward (through the screen) the bubble at render time.

Thanks guys!

It really starting to come together, but one glitch remains.

The text is now always like in the 2nd glitch window. Heres a snapshot:

http://i.imgur.com/Ipjpa.png

And this is the updated code:

[java]public ChatBubble(Node piv, String msg, boolean shout) {

BillboardControl bc = new BillboardControl();

bc.setAlignment(BillboardControl.Alignment.Screen);



Node holder = new Node(“CharBubble”);



String bubbleImage = “SpeechBubble.png”;

if (shout) {

bubbleImage = “ShoutBubble.png”;

}



Picture bubble = new Picture("");

bubble.setImage(MainClass.getAsset(), bubbleImage, true);

bubble.scale(2);





bubble.setIgnoreTransform(false);

bubble.setQueueBucket( Bucket.Transparent );

bubble.setPosition(-1, 0);



/* Material mat = bubble.getMaterial();

mat.getAdditionalRenderState().setPolyOffset(-1.0f,-1.0f);

bubble.setMaterial(mat);

*/

bubble.setLocalTranslation(-1,0,-.05f);

BitmapFont fnt = MainClass.getAsset().loadFont(“Interface/Fonts/Default.fnt”);



BitmapText label = new BitmapText(fnt, false );

label.setSize( .3f );

label.setText(msg);



float textWidth = label.getLineWidth();

float textOffset = textWidth / 2;

label.setBox( new Rectangle(-textOffset,0, textWidth, label.getHeight()) );

label.setColor(ColorRGBA.Black);

label.setAlignment( BitmapFont.Align.Left);

label.setQueueBucket( Bucket.Transparent );



label.setLocalTranslation(0,1,0);



holder.attachChild(bubble);

holder.attachChild(label);



holder.addControl(bc);

holder.setLocalTranslation(0,3,0);

piv.attachChild(holder);



}[/java]



I attach it all to a node, change the translation of the bubble a bit back in z, but the transparent issue will only

be solved when I move the bubble -.5f in z. That is too much, the text will look like it’s floating ontop of the bubble, constantly changing position :confused:

If you put the text and the bubble under the same node… and apply the billboard to that node as you’ve done then I’m not sure how the user would ever see the text floating since they are always looking at it from the same direction. In what situation can you see it floating?



I think the only other thing you could do would be to leave the setup like you have it (with the smaller offset) and either change the picture material’s additional render state to have a negative poly offset as Remy suggests or to do the same thing to move the text forward as I hinted.



Actually, something is weird anyway. What that picture says to me is that the bitmap text is being drawn first at a nearer Z and thus blocking the bubble from being rendered. Really the chat bubble should be drawn first (because it’s farther away). Though I guess that agrees with your having to set the bubble back even further… I’m just not sure why -0.05 isn’t enough to get it to sort properly.



…just as a test maybe try removing the billboard control just to see if they sort right then. Maybe it is confusing the issue.

I’ve got a similar problem to @Addez, I have some bitmap text which for some reason is getting the same “background” color as the viewport, when I want it to be transparent. This occurs with or without a BillboardControl. I only can only stop this happening by moving it at least 4 Z units towards the camera, which looks completely out of place, and even at some angles i can see artifacts appearing, ;s.

@Addez were you able to fix this issue with the artifacts around of the BitmapText? thanks in advance

There are several issues when using multiple viewports, even more so if you use post processing. If you do use PP, turn it off and see how that goes.

@wezrule if you do: label.setQueueBucket( Bucket.Transparent ); then that will be fixed.

if you don’t set queuebucket then it will be background color…

@madjack ok dam cus im using both of those :P. Well I just turned off PP and that didn’t solve it. It’s going to be hard for me to test without my other viewport now because my game relies quite heavily on it now, but I remember I still had this problem a while back before I added the 2nd viewport. Thanks for the tip tho.



@Addez yeh im already using that dam :(, thx though. But I noticed you already used that in your last post which still showed the artifacts in, was there anything else you did?

It shouldn’t be too hard to make a test case and see how it goes in a simple scene with no other viewport than the main one. When you get it fixed transfer the changes to the real app and see how that goes.

It helps to understand how transparency works. Unfortunately, there is no magic. And this is unrelated to viewports.



If you draw a transparent image right on top of another transparent image, ie: at the same depth from camera then what happens depends on the order drawn. I will use the chat bubble and the chat text in this example.



If the chat bubble is drawn first then it will draw and fill the Z-buffer with its current depth. The bitmap text will have trouble showing up at all as it will be writing to the same Z value in the Z buffer… sometimes you may see some of it as z-fighting based on the prevision of the Z buffer. Result: you see the chat bubble and no or nearly no text.



If the chat bubble is drawn second then the text will draw first and fill the Z-buffer with its current depth. The transparent pixels will be whatever the background was at the point the text was rendered. Text is rendered as a bunch of little quads with letter textures on them. When the chat bubble is then rendered second, it will only render to the places where the text wasn’t… because those Z-buffer values are already filled. As with the previous example you may see some Z-fighting.



There are two issues here:

  1. JME is sorting the items in its best attempt to draw them back to front. At best this is a guess because it is impossible to come up with a back-to-front scheme that works in all cases. It sorts them based on the nearest point to camera. So, for example, a big sphere at the same place as a small sphere will sort as being in front and so the big sphere gets drawn after the little one. And the degenerate example, a big quad behind a little quad will look right when viewed directly on but at an angle the big quad in the back is “nearer” to the camera and the sorting algorithm ends up making the front smaller quad get drawn first.


  2. once things are rendered then you also have the Z-buffer to worry about. Anything drawn that is further away than the last thing drawn at a particular pixel will not get rendered. This is why the transparent bucket tries to render back to front… so that all of the transparent items get drawn and don’t clip each other strangely (like in the case of the bitmap text and the chat bubble).



    In your last picture, JME was sorting in a way that caused the bitmap text to be drawn first. The little text quads filled the Z-buffer and so the bubble behind those little quads wasn’t drawn.
2 Likes

@madjack, im not too sure its related to the viewport, because I’ve only recently added my 2nd viewport (few weeks ago), and have had this problem since the beginning, thx tho.



@pspeed +1, i really appreciate the time and effort you gave to write that in depth analysis, it has given me and hopefully others a greater understanding about the war that is the Z buffer, I will experiment further, thx