gamefan Posted July 16, 2018 Share Posted July 16, 2018 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 Quote Link to comment Share on other sites More sharing options...
brianzinn Posted July 16, 2018 Share Posted July 16, 2018 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. gamefan 1 Quote Link to comment Share on other sites More sharing options...
gamefan Posted July 17, 2018 Author Share Posted July 17, 2018 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. brianzinn and DylanD 2 Quote Link to comment Share on other sites More sharing options...
Dad72 Posted July 17, 2018 Share Posted July 17, 2018 There are occlusions query for this. Meshes behind another: hide mesh.occlusionType = BABYLON.AbstractMesh.OCCLUSION_TYPE_STRICT; http://doc.babylonjs.com/features/occlusionquery Edit: Oops, I had read wrong, I understood inversse Quote Link to comment Share on other sites More sharing options...
gamefan Posted July 17, 2018 Author Share Posted July 17, 2018 @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? Quote Link to comment Share on other sites More sharing options...
Guest Posted July 17, 2018 Share Posted July 17, 2018 Mostly because it is webgl2 only gamefan 1 Quote Link to comment Share on other sites More sharing options...
brianzinn Posted July 17, 2018 Share Posted July 17, 2018 @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] Quote Link to comment Share on other sites More sharing options...
gamefan Posted July 18, 2018 Author Share Posted July 18, 2018 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. ? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.