Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] Add OccluderShapeMesh #52347

Closed
wants to merge 1 commit into from
Closed

Conversation

lawnjelly
Copy link
Member

@lawnjelly lawnjelly commented Sep 2, 2021

Add OccluderShapeMesh, glue to Occluder and gizmos etc.

This is still DRAFT, there is more work to do, but it should be able to start to be tested. As with OccluderSpheres, it can either be used with the portal system or be used on its own.

Includes:

  • Occluder baking
  • Mesh simplification (mesh optimizer is ported from 4.x - we don't have to have mesh simplification, but it is quite handy if there are no objections to including the library)

Following on from the Occluder Spheres, the second geometric occluder type I've called 'Mesh'. It is basically a bunch of convex polygons (with shared verts) where each polygon can be used as an occluder.

Baking

You assign a nodepath to a branch of the scene tree you want to use, and it recursively searches for meshes, and for each face decides whether to add it to the occluder mesh based on a threshold input size (area at the moment) and threshold output area. Preventing small faces is important for two reasons:

  • There are often lots of small polygons, and these take a long time to bake
  • We only want to use large polygons at runtime, as only large polygons make good occluders

That said you would often have a lower input threshold than output, because input faces will be merged when possible to form larger faces.

Occluder polys shown in magenta, active occluder polys shown in cyan:
occluder_mesh

The baking has three steps:

  1. Identify faces above the input size threshold that are suitable (marked as portal_mode STATIC, not using transparent spatial material, and matching the layer mask selected in the baker)
  2. Optionally simplify the triangles using the mesh optimizer third party library
  3. Join coplanar triangles where possible to form larger convex polygons. The threshold angle for coplanar can be adjusted.

Baked data is saved with the OccluderShapeMesh resource, but you can potentially bake them at level startup if desired to save on download size / work with procedural levels.

Inspector for the OccluderShapeMesh (subject to change)
Inspector_mesh

Runtime

At runtime similar to the spheres, the occlusion culler selects the most important polys based on a screen space metric to use for culling on any particular frame. You might have 1000 or so polys in the level, but only be using e.g. the default 8 at any one time (this can be changed in project settings).

The metric for finding the best occluders also removes polys that are themselves occluded by closer polys. There is no point in processing the further occluder if a closer one will already reject the objects.

Occluder merging

The biggest challenge for geometric occluders (as opposed to raster) is that it is far more difficult to deal with cases where an object is occluded by two or more polys, but not wholely occluded by any one of them. To this end the system has a basic geometric method for occluding objects that are behind 2 adjacent faces. This may be able to be improved to work with more faces in the future.

This roughly corresponds to two adjoining walls, or a wall and a floor, or wall and ceiling. This can work reasonably in many circumstances providing the occluding polys are large.

Scene
occ_polys_on_normal
Occlusion off
occ_polys_off
Occlusion on
occ_polys_on

Pros

  • It runs pretty fast and should be usable on mobile
  • It typically involves very little setup - just hit bake, and you are done. However you may want to make some allowance for transparent or moving objects, by choosing the branch to bake, and using masks, as you will not want these as occluders.
  • It can work with dynamic occluders
  • In an indoor level often quite a bit can be effectively occluded, almost as effective as portals in some situations

Cons

  • The occlusion is typically less predictable than other methods. Because of the geometrical methods, there are certain situations where the system cannot be sure an object will be occluded, so it will be rendered when you might not expect. This may also result in quite large changes in the number of rendered objects as you move the camera view.
  • There are no gameplay callbacks, so no opportunity to use it to throttle down AI etc

Dynamic use

While I was primarily envisaging larger numbers of polys used for static parts of a level, there is support for dynamic occluders, as with the spheres. If you transform an Occluder node (or parent etc) the mesh will be software transformed in the VisualServer and the new positions used for occlusion. This obviously works better if you don't go overboard with the number of polys in a dynamic occluder. A spaceship can probably have e.g. a box shape around it. As well as being faster, this also works better because larger occluder polys = better occlusion.

Typical use

  1. Add an Occluder node to the scene
  2. Choose new OccluderShapeMesh in the Occluder inspector
  3. Assign a nodepath to the branch you want to bake
  4. Hit Bake in the toolbar
  5. Profit

You can turn on and off occlusion in the View menu, and you may want to turn off the occluder gizmo once set up, as it provides a little 'too much' info at times... 😄

Comparison of methods

  • Raster occlusion (4.x) - Easy to setup, may not offer best performance or work well on mobile
  • Portals - Probably the fastest at runtime on all platforms, allows gameplay callbacks for managing performance (animation / AI / physics) - requires manual setup - Works with dynamic objects but expects the main scene to be static
  • Occluder Spheres - manually placed but very quick and easy to use - only useful for certain situations, especially occlusion by blocks of land etc - works very well in dynamic situations
  • Occluder Meshes - Easy to setup, auto baking, reasonably fast at runtime, should work fine on mobile - requires large occluders to work well. In some cases would benefit from manual placement of large polys specifically for occlusion. Reasonably good in dynamic worlds.

Status

Currently redoing the baking with a different method, flood filling neighbouring faces with similar normals, finding edges, then splitting into large convex polys. This seems to be much faster and is working much better, but still needs a few days work.

Update

This is taking longer than expected as there are a lot of special cases to deal with in the baking (I've spent 2/3 weeks solid on the baking), so it may well get pushed back to 3.5. I would rather get the existing functionality in 3.4 polished and out there, and spend longer on this to make sure it is robust. I'll keep working on it, but on a 'ready when ready' basis rather than pushing for a deadline. After the baking there are also some optimizations to choosing the best polys to do.

@Calinou Calinou added this to the 3.4 milestone Sep 2, 2021
@lawnjelly lawnjelly force-pushed the occluder_mesh branch 3 times, most recently from 08f6565 to 0720471 Compare September 2, 2021 19:27
@Calinou
Copy link
Member

Calinou commented Sep 3, 2021

I've started testing this. Great work so far 🙂

Testing project: test_occluder_mesh_3.x.zip
The editor takes a long time to bake when clicking Bake in the occluder menu (over 1 minute). Parameters are left to their default value and simplification is disabled. Not sure if it's due to my level mesh being too complex (it's a single mesh for the whole level) or something else. How long should baking take on a reasonably fast CPU? If baking occluders is often expected to take more than 8 seconds or so, there should be a progress dialog to avoid giving the impression that the editor froze.

After baking and hiding the Occluder gizmo using the View > Gizmos menu, rendering is slow due to the overly complex occluder, so I tried to enable simplification. Unfortunately, even with simplification set to 1 and the occluder baked again, I still get a lot of stuttering when moving around. (The culling is working as expected, still.)

We should see about enabling occluder simplification by default – a value around 0.1-0.2 would be a good default.

There's an usability issue I noticed too. If you create an Occluder node, the Bake menu option won't be available yet. This is expected, however, if you create an OccluderShapeMesh in the inspector, the Bake menu option will only appear once you select another node and select the Occluder node again.

To resolve this, I suggest we make the Bake button always visible regardless of the Occluder node having an OccluderShapeMesh resource assigned. If no shape resource is assigned, display a dialog that asks the user to choose a bake path, then create the OccluderShapeMesh resource and bake it immediately. If an OccluderShapeSphere resource is assigned, display an error dialog telling the user that they should clear the OccluderShapeSphere resource in the inspector before baking an occluder mesh.

You can look at how to pop up a node selection dialog in the CPUParticles menu option "Create Emission Points From Node". See particles_editor_plugin.cpp (base for the CPUParticles editor plugin) + cpu_particles_editor_plugin.cpp.

@timothyqiu
Copy link
Member

timothyqiu commented Sep 3, 2021

Some behaviors that I think are bugs / confusing:

  1. Create and setup an OccluderShapeSphere for the Occluder first, and then replace the sphere with a new OccluderShapeMesh in the Inspector, you can see the previous sphere occluder is still in effect.
  2. After rebaking, the cyan active occluder polys are not updated until I rotate the camera. i.e. If you move the mesh instance and then rebake, the cyan polys are still in the old place. Sometimes the old polys will be gone if I rotate the camera, but sometimes they'll be there until I switch to a different scene and back.
  3. Using a transparent material still makes the mesh instance an occluder. (See OccluderShapeMesh.zip)
  4. The "Bake Mask" property is unintuitive. I don't know how occluder baking works internally, so I have no idea whether it's referring to the physics layers or render layers, both seems make sense. But yeah, this won't be a problem after the documentation is written.
  5. Baking from CSGs and Sprite3Ds are not supported.

@lawnjelly
Copy link
Member Author

lawnjelly commented Sep 3, 2021

Good feedback. Yeah there is more work to do, just the basics are working now, but I thought it would be good for you guys to try in advance for exactly this reason to get feedback on how to improve it.

The editor takes a long time to bake when clicking Bake in the occluder menu (over 1 minute). Parameters are left to their default value and simplification is disabled. Not sure if it's due to my level mesh being too complex (it's a single mesh for the whole level) or something else. How long should baking take on a reasonably fast CPU? If baking occluders is often expected to take more than 8 seconds or so, there should be a progress dialog to avoid giving the impression that the editor froze.

I'll try this out. Currently with the baking, depending on the level, with too sensitive settings it is easily possible to overload the system - usually with a large level I would start with a large input threshold size and gradually lower it to increase the polys, rather than the other way around. Maybe this setting can be changed so that the slider is a target number of input polys, that way it is more likely to work at the same speed whatever the size / complexity of level.

I'll try this zip file in a second to give more feedback. I agree having about adding a progress bar and cancel button, and having a warning if the bake is going to take too long. There's also quite a bit in the baking that can be optimized more there I suspect.

After baking and hiding the Occluder gizmo using the View > Gizmos menu, rendering is slow due to the overly complex occluder, so I tried to enable simplification. Unfortunately, even with simplification set to 1 and the occluder baked again, I still get a lot of stuttering when moving around. (The culling is working as expected, still.)

I'll take a look. Aside from just drawing the gizmo (which could be expensive if you have e.g. > 2000 occluder polys) there is the possibility of a stall with how it currently shows the debug active polys, as it has to retrieve them from the VisualServer. This didn't happen on mine, but if it is a problem I can add some shortcut to add different type of thread protection to prevent stalling (this is already done e.g. for the portal callbacks).

We should see about enabling occluder simplification by default – a value around 0.1-0.2 would be a good default.

Possibly .. simplification has to be used with care at the moment I think. @JFonS was discussing this the other day for raster occlusion, which faces the same problem with simplification. If a convex mesh is simplified there is normally not a problem because the simplified version appears 'behind' the wall surface. But for a concave surface there is the possibility that the simplified version will appear in front of e.g. a wall, and start occluding stuff that should not be occluded.

Curved / overly complex surfaces in general can be a problem for these reasons, so it is usually better to exclude them completely (using the input threshold, or using layer masks or a different scene branch, or marking them as e.g. portal_mode DYNAMIC (which will prevent baking if you are not using portals) .. we could also potentially add a separate toggle somewhere to prevent occlusion baking like in 4.x).

There's an usability issue I noticed too. If you create an Occluder node, the Bake menu option won't be available yet. This is expected, however, if you create an OccluderShapeMesh in the inspector, the Bake menu option will only appear once you select another node and select the Occluder node again.

Yup I noticed that too, just hadn't got around to trying to fix it. It may be possible to get the editor plugin to refresh when you change the resource, that way the button will show. In fact this would be generally useful editor functionality imo, not just for this particular situation.

To resolve this, I suggest we make the Bake button always visible regardless of the Occluder node having an OccluderShapeMesh resource assigned. If no shape resource is assigned, display a dialog that asks the user to choose a bake path, then create the OccluderShapeMesh resource and bake it immediately. If an OccluderShapeSphere resource is assigned, display an error dialog telling the user that they should clear the OccluderShapeSphere resource in the inspector before baking an occluder mesh.

Hmm, yes it may be something like this could be added to make things more user friendly (although it does deviate slightly from the usual node / resource paradigm, as it does somewhat assume the occluder node will primarily be used for baking).

  1. Create and setup an OccluderShapeSphere for the Occluder first, and then replace the sphere with a new OccluderShapeMesh in the Inspector, you can see the previous sphere occluder is still in effect.

Ah yes this is a bug I had noticed on occasions. I'm hoping this is just a stale gizmo and a call to update_gizmo is needed at the appropriate time (it is also possible the spheres are not getting destroyed correctly, but I've seen a similar thing with polys themselves, and I think it's a gizmo issue).

  1. After rebaking, the cyan active occluder polys are not updated until I rotate the camera. i.e. If you move the mesh instance and then rebake, the cyan polys are still in the old place. Sometimes the old polys will be gone if I rotate the camera, but sometimes they'll be there until I switch to a different scene and back.

Ah yes this may be because the occlusion is not updated until a frame is rendered. So when baking is complete if I can request an editor screen refresh this should solve this. Presumably it doesn't occur in the continuous editor update mode?

  1. Using a transparent material still makes the mesh instance an occluder. (See OccluderShapeMesh.zip)

Yes I haven't thought this through very thoroughly yet, I basically copied the idea of checking standard materials for a transparent flag from @JFonS baker in 4.0, but this hasn't been properly tested yet. Custom shaders that use transparency / additive etc there may be some way of detecting. This can of course be done manually by selecting which meshes to bake but it would be nice to have it as automated as possible.

  1. The "Bake Mask" property is unintuitive. I don't know how occluder baking works internally, so I have no idea whether it's referring to the physics layers or render layers, both seems make sense. But yeah, this won't be a problem after the documentation is written.

Again copied straight from the 4.0 baker for now .. I haven't yet properly tested this / written docs. I'm actually not absolutely sure we need it (especially if we add a 'bake occluder' flag to visual instances), but I'll check with @JFonS the use case. It was pretty easy to add anyway.

  1. Baking from CSGs and Sprite3Ds are not supported.

Yes this is not done yet, but I should be able to add in a similar way to the Portal system. I'll have a look whether any common code can be put in a more sensible place (like constructing the CSG meshes if I remember right).

Some things to be aware of

It isn't highly optimized (or optimized at all in some cases! 😁 ) in terms of algorithms, especially for the baking and the choosing the best polys. I'm just concentrating on getting the basics working at first (i.e. something is better than nothing!). This can be improved over time, probably several fold.

For choosing best polys I may end up using e.g. a BVH against the camera planes as a first step. At the moment it is using brute force clipping every poly to screen space. This is probably fine for a few hundred polys but more than that some space partitioning / AABBs will probably help.

The actual geometrical culling technique I think can also be considerably improved in terms of rejecting more positives, but this basic version does work and provide a fairly decent starting point. It probably be time consuming refining this so I'd rather get the other functionality working well first, and we can refine this over e.g. the next beta.

@lawnjelly
Copy link
Member Author

lawnjelly commented Sep 3, 2021

The editor takes a long time to bake when clicking Bake in the occluder menu (over 1 minute). Parameters are left to their default value and simplification is disabled. Not sure if it's due to my level mesh being too complex (it's a single mesh for the whole level) or something else. How long should baking take on a reasonably fast CPU?

calinou_scene

There do seem to still be some improvements to the baking which would be nice to make. In particular in this scene there are a lot of convex polys which are not being merged because several need to be merged at once to maintain a convex face .. and at the moment it only does it one at a time. I might try reworking it to flood fill out and find all the coplanar faces in one go, then arrange these into the lowest number of convex polys, rather than doing it incrementally. It might work faster too.

Mesh must be split

Just having a look at this level. It's quite good for testing purposes, even though it is unlikely to work well, it's a nice kind of worst case. First of all, having a whole level (or most) as a single mesh means there can effectively be no occlusion culling, as only whole meshes are occluded. So such a mesh would at the very least need to be split into many parts.

It looks like this mesh has been imported with multiple surfaces instead of multiple MeshInstances. I'll try running it through my splerger addon as that will split meshes by surface. In Godot, culling operates at the level of Nodes, NOT surfaces!

Simplification values

It does show I need to tweak the simplification parameter that is passed to the mesh optimizer library. I wasn't sure exactly how this works, but it appears to be a fraction of the overall world size, so a value of e.g. 0.1 might not create much simplification in a small model, but in a large model it creates a lot. I already have code that is #ifdefed out that just determines the fraction of polys to be left after simplification. Alternatively we could have the simplification value be an absolute value in world space.

Level building technique - large polys versus polygon soup

The main problem with the level as far as the current system is that it has mostly not been made with any large occluding areas. This is an issue of modeling mostly .. For instance when building a large wall with a box against it, you can either build a single large wall, and a box, or some artists will build the box then split the wall around the box so that there is no unneeded area behind the box. The former approach is much easier to find large occluders, which the latter makes things far more difficult. The artwork approach tends to depend on the artist and the engine and tech they are making the level for. In some cases the latter can be better, but in this case the former works better. The good news is that a lot of simple levels and beginner designers tend to use the former approach, and it is quicker to work with anyway.

Manual Occluders

When a level comes as a polygon soup like this, you are probably better off manually adding some occluders (e.g. planes) in a separate branch, then baking these. I'm planning later to add an OccluderShapePoly type which should make this easier, which will essentially be an anti-portal, and allow easy editing of the points in the editor, and also merging several into an OccluderShapeMesh, or splitting a OccluderShapeMesh into several OccluderShapePolys.

Baking AI

The reason it is so hard for the baker to automatically create large occluders 'from nowhere', is that it can't make any assumptions about your level design. Some baking AI that works in one situation might break the occlusion in another. So at the moment you do have to work in a sensible way to help the system. Raster occlusion faces many of the same problems.

Portals conveniently works around a lot of these problems, because it essentially doesn't care what is in a room, the only things that need to be specified precisely are the portals themselves. This can actually make portals less work in some situations. This is a common theme in occlusion, there is no "one sized fits all" approach.

Floors

Something I experimented with that might be helpful on this level was the ability to prevent formation of occluders on floors and ceilings. Especially in a level such as this, it can potentially be quite handy, so I might add this to the Inspector. Essentially I just check an abs dot product of the poly normal with an up vector, and if it is close to the up vector, it ignores it. Things like terrain pointing almost straight down is pretty much useless for occlusion anyway. The screenshot above is with floors removed.

Occluders facing outward

Something I haven't added yet that will also help reject occluders during baking is that some simply cover the outside of the map, and could never occlude anything anyway. Consider a wall at the side of a map for instance. There is no point in having an occluder on it, in terms of baking or consideration at runtime. This might be possible by doing a search out behind the occluder for other geometry .. if none is found, don't add it, something like that.

@Calinou
Copy link
Member

Calinou commented Sep 3, 2021

Something I experimented with that might be helpful on this level was the ability to prevent formation of occluders on floors and ceilings. Especially in a level such as this, it can potentially be quite handy, so I might add this to the Inspector. Essentially I just check an abs dot product of the poly normal with an up vector, and if it is close to the up vector, it ignores it. Things like terrain pointing almost straight down is pretty much useless for occlusion anyway. The screenshot above is with floors removed.

This approach sounds interesting – I've never thought about it before. It might be worth porting to the raster occlusion in 4.x too. It won't work as well for highly vertical levels, but most game levels aren't highly vertical (they often have 1-3 floors at most).

Should this be exposed as a float property such as angle_limit?

@lawnjelly
Copy link
Member Author

Should this be exposed as a float property such as angle_limit?

I'm just adding it right now, it was already mostly in the code, just not exposed. Am thinking in terms of an angle in degrees, called something like remove_floors, with zero for off, and a value of around 10-30 to remove most non-useful terrain floors. That said, it is a very broad technique, and the moment you start having multiple floor buildings you will want some kind of control over this.

I think in the long run it should be able to combine this with some AI to detect whether there can be geometry below / above the poly in question, similar to the edge of map technique I mentioned earlier. Or you could manually mark some floors as not affected, I'm not sure yet what would be the best approach.

@Calinou
Copy link
Member

Calinou commented Sep 3, 2021

I'm just adding it right now, it was already mostly in the code, just not exposed. Am thinking in terms of an angle in degrees, called something like remove_floors, with zero for off, and a value of around 10-30 to remove most non-useful terrain floors. That said, it is a very broad technique, and the moment you start having multiple floor buildings you will want some kind of control over this.

Most angular property values in Godot are in radians rather than degrees, so I'd prefer to be consistent with other properties here. In 4.0, we have a way to convert degrees to radians in the inspector transparently (including a visible ° suffix).

Add OccluderShapeMesh, glue to Occluder and gizmos etc.
@lawnjelly
Copy link
Member Author

lawnjelly commented Sep 3, 2021

Ah I can change this. My personal preference is I find it depends on the setting. Degrees do have the advantage that they are easy to visualize for the user, and they can be stored as integers for things like this. For anything in radians, I would normally have to get the calculator out and convert from degrees manually.

But in some cases setting directly in radians can help. In actual fact it is used as a dot product in reality, and even this is easier to work with than radians, as at least it is between 0.0 and 1.0... 😁 Or even 0-100 angle-o-trons lol..

I'll probably redo the baking code significantly soon, this map has some good cases to cover. Once I have a good technique down and dusted we can put in the niceties like multi-threading and progress dialog... I've already got code for this from doing the lightmapping.

This approach sounds interesting – I've never thought about it before. It might be worth porting to the raster occlusion in 4.x too. It won't work as well for highly vertical levels, but most game levels aren't highly vertical (they often have 1-3 floors at most).

A lot of the principles involved in the baking here may be common for the raster occlusion in 4.0, so it's possible we may end up sharing some code / techniques. It may be something like the OccluderShapeMesh can't be used 'as is' for raster occlusion, for instance.

@lawnjelly
Copy link
Member Author

Just to update this, I've been solidly working on the baking, it turned out to be quite a rabbit hole! 😁

I'm really coming up with some fantastic stuff now (not pushed yet). This involved writing a new 2d decomposition method for polygons, and completely changing how it works. This result is calculated in under a second in debug .. compare this with the previous screenshot and you will see how much it has improved.
calinou_scene_911
There is still one more polygon decomposition case to check, then I'll look at tidying up and pushing.

It can still be improved in terms of maximizing the poly areas, but this may be able to be done as a simpler post process - i.e. if you have two split equally sized area polys you can often split them into a larger poly (better for occlusion) and a smaller one (potentially ignored) by adding an extra vertex and rejigging.

It should be emphasized that this map is worst case scenario, it's full of curved surfaces and broken wall areas etc. Feeding a complex polygon soup it's pretty miraculous it can come up with anything useful! 😁

@andersmmg
Copy link

Is there a reason cuboid/rectangular occluders are not mentioned here? I think a lot of the time, just some blocking out would be all that is needed rather than baking meshes. As far as I can tell, baking isn't exactly trivial and I for one would love to have a simple cuboid shape with a gizmo similar to the CSG cubes alongside mesh baking. It would still help a lot, especially with large buildings and the like for simpler or just less intensive games.

@lawnjelly
Copy link
Member Author

Is there a reason cuboid/rectangular occluders are not mentioned here? I think a lot of the time, just some blocking out would be all that is needed rather than baking meshes. As far as I can tell, baking isn't exactly trivial and I for one would love to have a simple cuboid shape with a gizmo similar to the CSG cubes alongside mesh baking. It would still help a lot, especially with large buildings and the like for simpler or just less intensive games.

Yes I'm planning on doing these too, but there's quite likely some shared implementation details in the VIsualServer side, so it makes sense to do the Meshes first. It may end up that boxes are implemented just a particular type of Mesh (i.e. when Meshes are working, you get boxes for free, aside from making the gizmos etc). Whereas spheres aren't sensible to do as meshes, hence they were done first.

@HeadClot
Copy link

Just to update this, I've been solidly working on the baking, it turned out to be quite a rabbit hole! 😁

I'm really coming up with some fantastic stuff now (not pushed yet). This involved writing a new 2d decomposition method for polygons, and completely changing how it works. This result is calculated in under a second in debug .. compare this with the previous screenshot and you will see how much it has improved. calinou_scene_911 There is still one more polygon decomposition case to check, then I'll look at tidying up and pushing.

It can still be improved in terms of maximizing the poly areas, but this may be able to be done as a simpler post process - i.e. if you have two split equally sized area polys you can often split them into a larger poly (better for occlusion) and a smaller one (potentially ignored) by adding an extra vertex and rejigging.

It should be emphasized that this map is worst case scenario, it's full of curved surfaces and broken wall areas etc. Feeding a complex polygon soup it's pretty miraculous it can come up with anything useful! 😁

Hey @lawnjelly - I have a question for you about the previous image.

What is the frames per second with the OccluderShapeMesh on the scene shown?
The info box in the bottom right does not say the FPS.

@Calinou
Copy link
Member

Calinou commented Oct 21, 2021

The info box in the bottom right does not say the FPS.

The editor FPS counter in 3.x is only reliable if you disable V-Sync in the project settings and set the editor update mode to Update Always. Otherwise, its value shouldn't be trusted. This was fixed in master by using Vulkan CPU/GPU timing information, which doesn't rely on the actual rendered framerate to give out a FPS estimation.

Either way, it's irrelevant in this particular scene as the whole scene is a single mesh. This means nothing will be occluded until small dynamic objects are added to the scene.

@HeadClot
Copy link

The info box in the bottom right does not say the FPS.

The editor FPS counter in 3.x is only reliable if you disable V-Sync in the project settings and set the editor update mode to Update Always. Otherwise, its value shouldn't be trusted. This was fixed in master by using Vulkan CPU/GPU timing information, which doesn't rely on the actual rendered framerate to give out a FPS estimation.

Either way, it's irrelevant in this particular scene as the whole scene is a single mesh. This means nothing will be occluded until small dynamic objects are added to the scene.

Ah ok, Was not aware of this thank you Calinou for filling me in on this.

Bit of a follow up question then for @lawnjelly:
Would it be ok from a performance perspective to use multiple OccluderShapeMeshes on various large parts of level geometry across multiple scenes?

For a bit of context - I am using Qodot in 3.4 RC1 to build out level geometry and I am splitting that level geometry across multiple scenes for performance reasons.

@lawnjelly
Copy link
Member Author

Would it be ok from a performance perspective to use multiple OccluderShapeMeshes on various large parts of level geometry across multiple scenes?

Yes, absolutely fine. The reason it is a mesh rather than a poly is just so things don't get out of hand in terms of number of nodes, and traversing the scene tree, but once it is in the visual server, the number of nodes doesn't matter.

In terms of what to expect as far as performance is concerned, it very much depends. At the extreme end you can get gains approaching what you would have with a properly portalled level, especially when you have large simple occluding walls. On the other hand if you have complex wall geometry that cannot be made into large occluders, you will get little benefit, because several small occluders cannot generally be merged (merging occluders is something that raster occlusion is much better at).

However I'm aiming to additionally have the ability to either add single occluders manually (like anti-portals), or mark e.g. invisible geometry like a MeshInstance plane as an occluder, which should make it more generally useful, at the cost of some manual work.

@akien-mga akien-mga force-pushed the 3.x branch 2 times, most recently from 71cb8d3 to c58391c Compare January 6, 2022 22:40
@EzraT
Copy link

EzraT commented Jan 8, 2022

Thank you!

@lawnjelly
Copy link
Member Author

Closing this as has been considerably rewritten since, and will be a second PR after #57361.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants