Sprite sometimes passing through a 3D model

Hi falks,

I am working on a project mixing plants made of sprite and 3D models for anything else. The problem is on some position my sprites passing through near 3D models. The thing is that apparently I cant use the Utility Layers of BABYLON to put my fence behind everything since sometimes the fence is in front of everything.

Soooo, does some of you know a possible solution for this problem ?
spriteThrough_3D

Hello and welcome to the community :slight_smile:

Can you repro in the playground ?

1 Like

I’ll try to do something soon

I’ve also encountered the problem; it happens because Sprites are billboard meshes. This means they are rotated automatically to face the camera at all times. If you put them in front of a 3D object, the rotation will lead to it intersecting with the mesh and the parts that are “inside” the other mesh are occluded if they both have the same rendering priority.

Unfortunately I’ve yet to find a solution that doesn’t feel hacky and often breaks. Here’s a few possible ideas that I’ve found online:

The latter seems promising, but I really don’t know Unity at all, so I can’t say if this would work in BJS or how to do it. It mentions an orthographic camera, so maybe it doesn’t even apply here.

Can you use sprites (or even regular meshes) in non-billboard mode, compute the occlusion based on the sprite’s position, and then afterwards rotate them to become billboards? That might help, assuming the rendering order is still based on the previous (non-billboarded) world position…

Hey rdw1, thanks for your answer.

There is some stuff in what you shared. But everything is always relative to orthographic camera with sprite front to camera with a 45 rotating angle. In my case, and maybe your’s, this is a perspecitve camera.

A solution I found, would be to use Utilisty layers of Babylonjs.

This class is originaly used for gizmos or ui stuff, but using it you can create a layer behind or above you scene with any object you want.

A good solution would have been to put my fence on an utility layer behind my scene and voila! The fence would always been behind everything else and my bilboard wouldn’t ever crossed it even if it does. This technique is used in first person shooter game so that your character never go inside a wall when you face it event if it should.

But in my case it is not ok since I have to be able to look my garden from outside, from behind the fence, or deal with L shape garden, where the fence is sometime in between camera and another part of the garden…

Anyway, it is maybe something you cold use in your case.
Thanks again, let’s keep digging!

Yeah, using layers doesn’t work if there needs to be proper occlusion between objects in the scene. Essentially, the sprites need to interact with “real” 3D objects like they were a non-billboarded plane, but they must appear as billboards in the final rendition. I have no idea how to do this, but I would assume there’s some magical way to transform the plane to billboard mode while still using the vertex positions of the original plane.

Here’s a quick demonstration of the clipping issue: https://playground.babylonjs.com/#YCY2IL#843

If you move the camera around, the clipping becomes even more visible. Behind the scenes, the tree is really just a 2D plane that intersects the box because it’s being rotated wildly to always face the camera.

Now, if we add a regular plane instead of the tree, the lack of billboard/rotation means the plane behaves as you would expect, which works great for fixed camera angles but is obviously not a solution for the scenario we are talking about: https://playground.babylonjs.com/#YCY2IL#844

If we imagine the camera moving and the sprite being billboarded, the result (without using the actual camera angle) would be something like this: https://playground.babylonjs.com/#YCY2IL#845

Here we see the clipping very clearly from the point of an outside observer (not the actual camera/viewer, which would be located to the southwest/above, orthogonal to the plane). What should happen to avoid it, is that the plane should be treated as though it was in the original, non-rotated position (first playground introducing the plane) for occlusion/layering purposes, and then rotated to face the camera (billboard effect) only after the rendering order has been determined. Can that even be done? And would it eliminate all the clipping? Who knows…

Unfortunately, that’s as far as I’ve gotten with respect to this problem. Maybe one of the wise Babylon 3D gurus has a better idea?

2 Likes

cc maybe @PatrickRyan our 3D wizard has some trick

Trying to think about it, one option would be, for each frame, to raycast from the camera to a grid of positions on the sprite plane, and check if any of them is blocked by another mesh. If it is, we could either not draw it, or to put it into a higher layer. Another option to check the “blocking” status could be by using occlusion culling, WebGL 2 Example: Occlusion Culling (tsherif.github.io), webgl2examples/occlusion.html at master · tsherif/webgl2examples (github.com). Patrick might have a way simpler trick tho :sweat_smile: he’s out this week but he’ll check this out next week.

2 Likes

Hi @carolhmj ,

thanks for sharing this. It might be a good option to raycast from the camera. I’ll give a try to it. The thing is that I have a lot of sprite in front of each other.

One good option would be to detect if a sprite near of the border pass through, working on it width max size from the center and see if it pass through border or not.

If true find every sprite, based on there center, in front of my sprite and put them all on another layer. I’ll try that for sure and see if it doesn’t overload to much my scene

Thanks for the sharing!

That’s definitly a start, thanks for giving a try :+1: