gamefan

Ideas on showing mesh hidden by other meshes with some transparency

Recommended Posts

Hi everyone,

I was wondering if there is a way to show a mesh hidden behind another mesh other than by setting its renderingGroupId. I want to always show a highlighted mesh which is being interacted by user even if its blocked by other meshes. Drawing it over everything using renderingGroupId sort of confuses depth perception. Is there a best of both worlds? Perhaps by setting some transparency to the blocking meshes, but how to get the list of meshes blocking a mesh's visibility?

Thanks
 

Share this post


Link to post
Share on other sites

This is far from a perfect solution, but to get this started.

1. See if the mesh that could be hidden is in the camera frustrum, if needed:

var frustumPlanes = BABYLON.Frustum.GetPlanes(camera.getTransformMatrix());
mesh.isInFrustum(frustumPlanes)

2. If your mesh is in the frustrum, then get the mesh bounding box or loop through all the mesh vertices and cast rays at each of the vertices with multiPick using something like lookAt() to get the normal to that vertex?  This is the part that would kind of work, but surely has a lot of room for improvement.  I am interested to hear how this is done properly.

It's flawed, because it could still miss meshes.  I can see multiple edge cases where that solution wouldn't work. :)

Share this post


Link to post
Share on other sites

Great Idea. I made rays from bounding box corners to camera's position. Something like this:
 

var boundingInfo = activeObject.getBoundingInfo().boundingBox.vectorsWorld;
for (var i = 0; i < boundingInfo.length; i++) {
	var ray = pickingRays[i];//pre defined rays for reuse
	ray.origin = boundingInfo[i];
	scene.activeCamera.position.subtractToRef(ray.origin, ray.direction);
	ray.direction.normalize();
        ray.length = BABYLON.Vector3.Distance(scene.activeCamera.position, ray.origin);
	for (var j = 0; j < scene.activeCamera._activeMeshes.length; j++) {
		var mesh = scene.activeCamera._activeMeshes.data[j];
		if (ray.intersectsMesh(mesh, true).hit) {
            		mesh.visibility = 0.5;
                }
	}
}

I never knew there was a multiPick, its there as scene.multiPick and scene.multiPickWithRay. This helped in other areas. So double thanks for the bonus 😉
The above solution works just right, but I would love to see if there were a better/efficient solution.

Share this post


Link to post
Share on other sites

@Dad72

Nevertheless an interesting feature. Today is good. 😀

So if I understand it right, the engine will automatically discard meshes outside the camera frustum in the render cycle. But has to draw everything that is inside because it cannot decide before hand about the depth?
We can thus use occlusion queries to disable render of a mesh hidden by an opaque mesh. This is neat, wondering why its not internally used in the engine. Perhaps because its asynchronous or slow?





 

Share this post


Link to post
Share on other sites

@gamefan thanks for sharing your solution.  i was hoping somebody would share a better solution as well - really was just sharing that to start and waiting for something better...

I didn't know about ray.intersectsMesh(), so we both learned something new! If that is useful to others, would be nice to encapsulate that in something like a single point to mesh (like a cone shape), and have intersectsMesh(...) available on that with maybe options for BoundingBox or MeshVertices - Let's call it MultiRay :)
Also, scene has a public getActiveMeshes() [http://doc.babylonjs.com/api/classes/babylon.scene#getactivemeshes]

Share this post


Link to post
Share on other sites
18 hours ago, brianzinn said:

Also, scene has a public getActiveMeshes() [http://doc.babylonjs.com/api/classes/babylon.scene#getactivemeshes]

Yes, Just got lazy there 😅, but yeah its unsafe to use non public variables

 

18 hours ago, brianzinn said:

I didn't know about ray.intersectsMesh(), so we both learned something new! If that is useful to others, would be nice to encapsulate that in something like a single point to mesh (like a cone shape), and have intersectsMesh(...) available on that with maybe options for BoundingBox or MeshVertices - Let's call it MultiRay :)

Yes, can have something like Mesh.prototype.isVisiblyBlocking = function(targetMesh, fastcheck, camera)
fastcheck true uses bounding box, otherwise mesh vertices. Happy to make PR if need be. 😉

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.