Particles clip at certain angles

Hello,

I’m trying to make a simple maze game, and I thought it would be neat to add some torches with a fire effect to them. They’re working just fine so far, but the only problem is that the particles clip against my wall at certain angles. Here’s an example of clipping:

http://i.imgur.com/TJ9iJND.jpg

And here’s an example of an angle where it doesn’t clip:

http://i.imgur.com/Bhi5wsC.jpg

I suppose I could subdivide my wall further (each grid segment of wall is literally just two triangles), but is there a way to configure the particle emitter to not clip like this?

Thanks!

Oh, and here’s how my particle emitters are configured right now:

http://pastebin.com/wHBWQsgv

I can provide any other code as needed.

My guess is that your walls and your torch flames are in the same queue bucket. The walls should be in the opaque bucket and the flames in the transparent bucket.

Unfortunately, that didn’t work: I’m still seeing the same effect. What I did was add the line

[java]fire.setQueueBucket(RenderQueue.Bucket.Transparent);[/java]

At the end of the method I pasted above and added

[java]wall.setQueueBucket(RenderQueue.Bucket.Opaque);[/java]

when initializing my walls and torches. Is there anything else I need to do to make the queue buckets work as they should?

This isn’t really an easy thing to fix - other than by moving the fire further from the wall or otherwise constraining the particles.

You could turn off depth test on the particle - but that would then make them show in front of everything.

You could use the new ParticleController particles and write your own custom billboard-mode that avoids turning into the wall - but that would be computationally expensive if you have a lot of walls.

Honestly your best bet is just to set up the particles so they don’t go into the wall - or have enough particles that the line is less obvious.

@pspeed said: My guess is that your walls and your torch flames are in the same queue bucket. The walls should be in the opaque bucket and the flames in the transparent bucket.

I don’t think this is bucket related, the flames are depth testing against the wall and since billboarding has push them behind the depth test stops it rendering there.

@zarch said: I don't think this is bucket related, the flames are depth testing against the wall and since billboarding has push them behind the depth test stops it rendering there.

Except in the first pic, it looks like the torch is much closer than the wall, billboarding or not… and yet the entire wall is clipping the torch even the parts that should be billboarded further away from the wall (ie: closer to the camera)… exactly as if depth write is off for the flame (as it should be) but the flame is being drawn before the wall (as if it was in the opaque bucket).

I still stand by this is likely a bucket issue and I’m doubtful that the buckets are setup correctly even after fixing them somehow.

Looking again… it’s acting more like they are both in the transparent bucket. But it’s really hard to say from static images.

OP, if you can put together a simple single class test case it might help you find your issue… (like one wall, one torch). And if not then we have something easier to swallow to sort out the problem.

Ok, I’ll try putting that together. For now I just edited the torch model so it’s higher and sticks out a bit more from the wall. That will do until I find a better solution. :stuck_out_tongue:

Ok, here’s a single class test case.

https://mega.co.nz/#!SJAWgLRR!d4zaTz17Af9upYxgr1yDdArer7RNTPPuKQra6NHvGTE

You can move the flycam around so you are looking at the wall from the side, and the effect is obvious.

EDIT: I also tried subdividing the wall and that didn’t work either.

1 Like

+1 for a fantastic test case!!

The children of the imported wall model are in the transparent bucket, which is causing the issue. I don’t know why, its something to do with the blender importer I guess, perhaps in Blender they have some transparency set on them (I really have no idea about that side of things).

Setting the bucket on a parent node does not explicitly apply that bucket to the children, (perhaps this is a bug ?), so what you are doing in your test case is correct, it’s just not working.

I figured this out, and fixed it by adding the following …

[java]
Node n = (Node) wall;
for (Spatial c : n.getChildren()) {
System.out.println(n);
Node n2 = (Node)c;
for (Spatial c2 : n2.getChildren()) {
System.out.println(">>"+c2.getQueueBucket());
c2.setQueueBucket(RenderQueue.Bucket.Opaque); // This is the fix
}
}
[/java]

…which ouputs…

Textures/maze12.blend (Node)
Textures/maze12.blend (Node)
Textures/maze12.blend (Node)
>>Transparent
Textures/maze12.blend (Node)
>>Transparent
Textures/maze12.blend (Node)
>>Transparent
Textures/maze12.blend (Node)
>>Transparent
Textures/maze12.blend (Node)
>>Transparent

It’s a dirty hack but it helps highlight and fix the issue.

Another hack fix would be to put the particle emitter in the Translucent bucket, which gets rendered after the Transparent.

Cheers
James

1 Like

Also, for the record… a perhaps simpler way when you remember how to do it (I also use recursive methods a lot but I’ve been trying to use this approach more):

[java]
Spatial someSpatial…

someSpatial.depthFirstTraversal( new SceneGraphVisitor() {
public void visit( Spatial s ) {
s.setQueueBucket(Bucket.Inherit);
}
});
[/java]

a) showing an example of a scene graph visitor to do something like this in only a few lines of code.

b) bonus: shows using Bucket.Inherit so that the children will just inherit their parent’s setting.

Note: in the above, someSpatial also gets visited and so afterwards you can set someSpatial to whatever bucket you want and its children will inherit it.

1 Like

Awesome, that completely fixed it! I took your solution and made this method out of it:

[java] private void setQueueBucketRecursive(Spatial c, RenderQueue.Bucket b) {
c.setQueueBucket(b);
if (!(c instanceof Node)) return;
for (Spatial child : ((Node)c).getChildren()) {
setQueueBucketRecursive(child, b);
}
}[/java]

I just replaced all my calls to c.setQueueBucket(b) with setQueueBucketRecursive(c, b). Fixed the issue just fine. :slight_smile:

And about the blender model, I’m not sure what’s up with that either. The wall model was originally made in Maya. I tried exporting to OBJ from Maya and importing that directly into jmonkeyengine, but some of the normals were in the wrong direction. What eventually worked best was editing it in blender, fixing the normals, saving to a blend file, then importing the blend file instead of the OBJ file. I’m sure I’ve done something wrong in that convoluted process, so this is probably my fault. Here’s the .blend and .obj file for the wall if anybody wants to know if this is a blender import bug or I just messed things up too much (if anybody actually looks at this, please don’t laugh at my lack of UV mapping skills!):

https://mega.co.nz/#!vYwTVRZL!AETHRnSBTbDGnRWKaEpmvEhP441I5aM50SuXkAx_Td0

Thanks again for the help!

EDIT: of course now I see pspeed’s much better method. Thanks for that, I didn’t know about the traversal classes. :slight_smile:

Looks like it’s your blender material setup :

1 Like

Awesome, that makes sense. I guess this is what I get for literally not using Blender at all until a week ago. :wink: