-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Allow server side occlusion culling. #5320
Conversation
@Fixer-007 what about it? :) |
If network lags while I'm walking on server, will culling then also lag? |
src/clientiface.cpp
Outdated
@@ -298,6 +301,12 @@ void RemoteClient::GetNextBlocks ( | |||
if(block->getDayNightDiff() == false) | |||
continue; | |||
} | |||
|
|||
if (occ_cull && !block_is_invalid && | |||
env->getMap().isBlockOccluded(block, cam_pos_nodes)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (occ_cull && !block_is_invalid &&
env->getMap().isBlockOccluded(block, cam_pos_nodes)) {
EDIT: http:https://dev.minetest.net/Code_style_guidelines#Spaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops. That one slipped through.
src/clientiface.cpp
Outdated
@@ -197,6 +197,9 @@ void RemoteClient::GetNextBlocks ( | |||
s32 nearest_sent_d = -1; | |||
//bool queue_is_full = false; | |||
|
|||
v3s16 cam_pos_nodes = floatToInt(camera_pos, BS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I knew that would come up. :)
We're kinda schizophrenic about this. I'll change it.
@lhofhansl Is this considered as an alternative method to prevent blocks from being sent to the clients like pull #5309 would do? |
@Fixer-007 The server side culling is independent on that. |
@SmallJoker This is definitely related to #5309 and #4811 . |
But in fact this can replace all the other server side optimizations. |
@lhofhansl Come to VanessaE Dreambuilder Survival or Creative (or other VanessaE's servers), they have this patch. |
@Fixer-007 Are you saying something broke or renders incorrectly or is slowing down? I tested with my own server and mostly focused in the number of blocks the client reports as "seen". |
@Fixer-007 Cool. I might do that. Never actually player on a public server :) What this does it just has the server filter the blocks to send by what the play would actually see. There are other mechanisms that take the player's position into account, so I would not expect this to cause new visual lag. I'll do some tests with some scenes and compare the day-night spread optimization (which leads to rendering issues) to the occlusion culling. |
Update style and const declaration. No functional changes. |
To make review easier...
The change looks bigger than it is, because I had to move some code around. |
Looks like max_block_send_distance is set only to 3 on that server (I can see the edge of the world with a v_range > 50). Is that true? |
Some numbers: Water scene:
Land scene:
v_range was 200 |
These two scenes should be somewhat the worst case. So this is clearly superior to #5309 , and this will always render correctly (if the culling is incorrect it is incorrect in exactly the same way the client culling is incorrect). I think we can remove the WIP status from this. |
Only concern is potential CPU spent on the server to do occlusion culling for each player. The upside is that at any point only blocks are sent to the client that the player can actually see. |
Is occlusion culling also disabled on the client? I guess it is because it is less effective so would not be of any use.
What does this mean? Can we still fly underground with noclip? (essential for dev work). What is it about server occlusion culling that makes it more effective than on the client? |
So amount of rendered stuff will increase by 35-50% ? Thats a lot of fps drain :( |
@Fixer-007 We'll keep the day-night optimization - which has the rendering errors. Server side occlusion help even on top of that. But when you want correct rendering, than occlusion culling can give you that and save blocks (in tight caves that can be saving 90% or more). |
No it's not. Server culling just makes sure that the server does not send blocks the player cannot see. Since the player moves around, there will be cached blocks on the client that still should not be rendered, so client side culling is still useful.
Flying around with noclip still works, but the client will naturally have fewer blocks to see, that's all.
It doesn't. It's the same logic. It just happens before the blocks are sent to the client, rather than after. |
I see, thanks, seems good. |
Just to make 100% sure, you set server_side_occlusion_culling to true in your minetest.conf file, right? :) |
Heh. Glad I asked. On the server only. |
Let me turn this default on. |
Turned on by default now. |
As discussed in #5309 perhaps now it's time to increase |
I think it's safe to turn this on and set |
Anything else I need to do with this? This saves a bunch of block sending from server to client. Since this uses the same algorithm on the server that we have been using on the client this will never miss blocks that client occlusion culling would not filter out as well. |
Sorry for quiet dev, many devs seem to be absent or busy at the moment, and the few left overwhelmed, i think this has a lot of potential, we are very interested and i'll try to look as soon as i can. I support the concept. |
(Yeah back from travel - work still keeping me busy, though. Happy to help wherever I can, with code, reviewing, keeping the code sane, etc) |
Oh and FPS should be unaffected. The complexity of the rendered scene is exactly the same. |
👍 |
It's worth benchmarking the server, and seeing [if/how much] it reduces load |
Ran it through the Linux perf counters. The difference I'm seeing are within the noise. Without this PR I see perhaps a little more time spent in malloc (1% or so). With the PR I see (also 1% or so) in Map::getNodeNoEx and Map::getSectorNoGenerateNoExNoLock. All within the noise of a few runs. Like the day-night light test optimization to see whether a block is near ground level, the blocks needs to be actually loaded in order to do occlusion culling (again just like for the day-night optimization), so I would not expect lighter load on the server; just lighter load on the network. (Next step is making the occlusion more effective - i.e. re-visiting #4933 ) |
Put some counters into the server to verify that the client's "blocks in range" does reflect the number of blocks sent from the server. It does :) |
This also helps against cheating, doesn't it? |
@HybridDog yes it would incidentally help with that, but you couldn't rely on that. You can just fly around and look at the scene from different angles and over the time the client would cache the scene from all sides and you'd be able to do the very same hacks. |
Can you automatically temporary disable server side occlusion culling for players which aren't in caves (test if they stay in sunlight) when the server has a high CPU usage? |
^ That's not a good idea. |
It would only be a good idea with Occlusion Culling would be computationally expensive. |
How computationally expensive is it on a high-traffic server? At peak hours I average about 45-50 connected players. The potential gains on the network side are appealing, but I'm concerned this patch might prove to be a performance drain for the CPU. Thanks. |
By far the main drain is handling ABMs (also done per player). Occlusion culling is not measurable compared to the ABM cost, it's within the noise of the measurement. In the end I have no way to experimentally verify that with dozens of players, though. If it turns out to be a CPU drain for a specific server it can always be turned off via the config option - but I really doubt it will ever be a problem. |
👍, this will be good for mp servers |
Moved occlusion culling code from ClientMap to Map.
Changed transparency condition from
to
f.drawtype == NDT_NORMAL
This is needed so the same code can be used on client and server without virtual dispatching in hot code path.
(see ContentFeature::updateTextures for why this is correct)
In my tests this saved between 50 and 80% of the blocks sent to the server when block_send_optimize_distance is set to the maximum with no visual impact.