Masking/clipping a scene with a polygon shape

Hello,

There is something I’d like to accomplish and have no idea where to start. I have a scene like this one:

Here is a live link if you want to test it.

I’d like to be able to define an arbitrary zone by a polygon and render what’s inside the polygon, hide that’s outside the polygon. Let say as follow:

It would work like clipping planes except the definition of the “cut” is not just a plane.

Other detail I can think of: some meshes will need to be cut at the intersection, and I would prefer having them look “full”, not “empty”.

Any idea where to start? Thank you :pray:.

If you are using Babylon embeded material and the side of your polygon region is no more than 6, you can use the Babylon clipplanes.

If the number of side is larger than 6 or you are using some customized material, you can define the polygon region by several plane functions like ‘a * x + b * y + c * z + d = 0’, do a inside/outside check within fragment shader like

bool checkWithinClipPlanes(vec3 position) {
    bool inside = true;
    for (int i = 0; i < numPlanes; ++i) {
            vec4 plane_eq = u_Planes[i];
            float distance = position.x * plane_eq.x + position.y * plane_eq.y + position.z * plane_eq.z + plane_eq.w;
            if (distance < 0.0) {
                inside = false;
                break;
            } 
        }
    }
    return inside;
}

void main() {

    if (!checkWithinClipPlanes(worldPos)) {
        discard;
    }

}

Note the number of planes could affect the performance of your shader. And if the numbers are too big, you probably need a texture to store the plane equations to avoid limit of uniforms size.

2 Likes

Thanks a lot for this reply @xiasun :star_struck:. I’m guessing this would only work for convex polygons right?

I did guess I might end up going in the direction of shaders. I haven’t used them before so it’s a big (scary) step to take. Is there a reason the shader code uses plane equations here and not a point in polygon type check?

Also I’m curious, in term of performance, when is that shader code executed? Can it be done at scene creation or must it be done during each render loop?

Thanks a million again!

I’m sorry, I just have to ask: How much ‘arbitrary’ is it? I’m asking because it looks to me that you want to do it ‘per room(s)’. Not cut one right in the middle, is it? If so, just wondering why you would not simply just create groups (for each room) and eventually area (for an extended ‘group’ of rooms). Then you could just setEnable(true/false). Simple, Efficient. No rendering and no further processing of the meshes that are disabled. Also best way to keep this ‘consistent’ I believe. Probably sounds a bit too simple… Likely I’m missing something, am I?

1 Like

Thanks the suggestion and creative thinking @mawa.

So it is really arbitrary, we support a wide array of use-cases and don’t have visibility on what our users could do.

But even if we decided to constraint to what you call “groups”. The exterior wall of the space that goes all around could very well be a single mesh that I can attach to a group in particular. And this is just an example, there is no known relation between rooms and walls that often span many rooms. I’m not sure if I’m clear on this.

Does that eliminate your option or did I misunderstand something?

Thanks :slightly_smiling_face:

1 Like

Yes, well. I thought be a little bit more complex than just that :grin: That sounds more like an editor.

Well, you can call it ‘groups’ or ‘rooms’ or ‘prefabs’. And when you say ‘constrain’, it could also be ‘build’ or ‘generate’. Similarly to a dungeon, when 4 walls sort of connect together, it creates ‘a room’.

Yes, indeed. In case of an editor, there’s a distinction to be made I believe between exterior and interior walls. But a wall could be split whenever it connects with another (i.e. this is also true for interior walls, of course. In case of an interior wall, it can also be ‘shared’ among two rooms, remaining enabled/disabled when either ‘room’ is active/inactive.
The idea in fact wasn’t just entirely original. It comes from an old build in Unity of a dealership creator/editor, where the user could draw his architecture and then add structures and furnitures and displays and stuff. We needed to have the capacity of defining areas and include a customer path and calculate a number of things around these areas (surface encombrance, windows/light, add recom for hotspots based on these calc… you know stuff like that.)

That won’t be mine to tell (I’m glad it isn’t :sweat_smile: :joy:). Anyway, thought it was worth suggesting. Sometimes, thinking of a different approach cannot harm :grin:

1 Like

It definitely helps!

Another approach I thought about, which is somewhat related, is to take every “feature” I have, let say walls to simplify. If the wall is in the polygon render it, if it’s out don’t render it, if it intersects then cut the feature into 2 (or more for multi points intersections) and render the part(s) that’s in.

1 Like