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

Fix incorrect distance computation for visible blocks #4765

Merged
merged 1 commit into from
Nov 11, 2016

Conversation

Rogier-5
Copy link
Contributor

@Rogier-5 Rogier-5 commented Nov 10, 2016

The client would not compute the distance from the camera to
to a mapblock correctly. The result was that blocks that were in
view (i.e. not beyond the fog limit) would not be rendered.

See issue #4763 for a discussion and screenshots

@SmallJoker
Copy link
Member

SmallJoker commented Nov 10, 2016

What if you would increase the range in this function by (BS / 2) * sqrt(3) to reach the blocks that are a bit further away too? Bad idea?

@paramat
Copy link
Contributor

paramat commented Nov 10, 2016

👎 This may work perfectly, but too perfectly, it is a lot of code to put into 'isBlockInSight()' which needs to be as lightweight and fast as possible. Better to just make a very simple imperfect fix by changing a single number somewhere, such as the recently used 'range', such that mapblocks are drawn slightly beyond the fog instead of slightly in front.

@lhofhansl
Copy link
Contributor

I also feel that this is bit overkill perhaps. We use the center of the mapblock, which is not perfect, but it seems good enough.

Also note that isBlockInSight is used in clientIface.cpp to control the retrieval of blocks from the server. Need to make sure this is not affected.

@paramat
Copy link
Contributor

paramat commented Nov 10, 2016

Yeah better to pass an adjusted value for range elsewhere.

@paramat
Copy link
Contributor

paramat commented Nov 10, 2016

I guess this started happening due to e7c62ed ?
Also, the way your fog behaves affects this, with shaders fog cuts off in a circle, closer to the camera, without shaders it's either circular or a box depending on your system.
Problem is, making more blocks drawn decreases performance, and we should not be too concerned with very short view ranges.
So i'm unsure this should be fixed.

@lhofhansl
Copy link
Contributor

I doubt this has anything to do with e7c62ed. There we do not use the fog distance or anything, but use max_block_send_distance, which is fixed. Also in these cases the block has already been seen by the client, so it wouldn't disappear again.
Pretty sure this is a client side thing only.

@paramat
Copy link
Contributor

paramat commented Nov 10, 2016

Ah yes i was mixing things up.

@Rogier-5
Copy link
Contributor Author

Simpler code here may indeed give a better performance tradeoff than more processing later, especially since the graphics processor will be doing part of that extra work.

@lhofhansl: The patched code necessarily selects more blocks, so the retrieval of blocks from the server would only be affected in the sense that network traffic and server load might increase, but for a good cause.

@SmallJoker's suggestion to adjust with half the maximum block diameter instead sounds good, and it solves the issue. I have adjusted the distance that is computed (d) instead of the range, because the distance is used later, and its value must match the decision taken by isBlockInSight(). I revised the commit & pushed it.

@lhofhansl
Copy link
Contributor

lhofhansl commented Nov 10, 2016

Thanks @Rogier-5 . What I was trying to say was: Let's adjust the radius at the place where we call isBlockInSight. I do not think we want to increase the radius for block retrieval, so let's not change isBlockInSight, but change the relevant callers.

@lhofhansl
Copy link
Contributor

Actually I take that back. In e7c62ed I pass in (full_d_max + 1) * BS * MAP_BLOCKSIZE to range. With the change here we can do away with the +1 part in there, which would make sightly more sense. Lemme try that.

@Rogier-5
Copy link
Contributor Author

I do not think we want to increase the radius for block retrieval

The blocks that are rendered will have to be fetched from the server at some point...

What is the reason for wanting to fetch less blocks ? If fetching less blocks is the goal, then it seems more logical to implement that at the location where the blocks are fetched from the server. I don't know how that is done ATM, but I suppose far-away blocks could be transferred less often anyway.

Let's adjust the radius at the place where we call isBlockInSight

Would that be more efficient ? Because IMHO it would certainly be more obscure: adjusting the range everywhere else, instead of in a single place, inside isBlockInSight(). That would certainly require clarifying comments.

BTW: I tried the patch without adjusting d (by adjusting range inside isBlockInSight()), and it failed. For some reason I didn't investigate, the blocks still didn't get rendered. Only by adjusting d did I get the desired result.

@lhofhansl
Copy link
Contributor

OK. I changed (full_d_max + 1) * BS * MAP_BLOCKSIZE to just full_d_max * BS * MAP_BLOCKSIZE and with your change the retrieval range is mostly unchanged (but still as far as the side of the cube would have been before e7c62ed). So that's slightly better anyway.

Interestingly, the returned value of d has to change for your fix to work. For kicks I just changed it to if(d > range + block_max_radius) and did not change d itself, and that does not fix the issue. So it's something a caller does with the returned value.

In any case. +1 to this change now. Can you also make the change I mention in clientiface.cpp? (Without that we'd be increasing the retrieval range).

@lhofhansl
Copy link
Contributor

Perhaps

// Total distance
f32 d = MYMAX(blockpos_relative.getLength() - block_max_radius, 0.0f);

Instead of the if-statement (but now I'm nitpicking).

@paramat
Copy link
Contributor

paramat commented Nov 11, 2016

^ Yes that would be preferable.

This PR looks good now 👍 as it seems you have both tested.

@lhofhansl
Copy link
Contributor

👍 on latest. The MYMAX thingy looks a bit nicer, but that's it.
Thanks @Rogier-5 .

The client would not compute the distance from the camera to
to a mapblock correctly. The result was that blocks that were in
view (i.e. not beyond the fog limit) would not be rendered.

With the improved distance computation, a range adjustment that
existed in clientiface.cpp is no longer required.
@Rogier-5
Copy link
Contributor Author

OK. Changed MYMAX too...

@Zeno-
Copy link
Contributor

Zeno- commented Nov 11, 2016

seems good
👍

@kwolekr
Copy link
Contributor

kwolekr commented Nov 11, 2016

👍

@Zeno- Zeno- merged commit b98f98b into minetest:master Nov 11, 2016
*/
bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
f32 camera_fov, f32 range, f32 *distance_ptr)
{
// Maximum radius of a block. The magic number is
// sqrt(3.0) / 2.0 in literal form.
const f32 block_max_radius = 0.866025403784 * MAP_BLOCKSIZE * BS;
Copy link
Contributor

@Zeno- Zeno- Nov 11, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rogier-5 Just for future reference, some of us prefer that stuff like this is static const qualified rather than just const qualified. I doubt it makes a difference with modern compilers (easy to check) and it's more of a "style" issue, but static const is IMO (from code I look at is more "common" and "idiomatic") is what I prefer, and obviously some others in #minetest-dev and other programming channels agree. It's a nitpick; not important really; and just "one of those things", which is why this was merged as-is (plus is consistent with code above anyway). Just thought I'd mention it for interests sake.

@Rogier-5
Copy link
Contributor Author

@Zeno- Thanks.

Actually, I did consider static, but I reasoned it wouldn't make a difference anyway (compiler-wise), so I left it out...

I'll use it next time.

@Rogier-5 Rogier-5 deleted the mapblock-render-distance branch November 11, 2016 09:18
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.

None yet

6 participants