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

Implement visibility range and dependencies #48847

Merged
merged 1 commit into from
Jun 14, 2021

Conversation

JFonS
Copy link
Contributor

@JFonS JFonS commented May 19, 2021

This commit adds the following properties to GeometryInstance3D: visibility_range_begin,
visibility_range_begin_margin, visibility_range_end, visibility_range_end_margin.

Together they define a range in which the GeometryInstance3D will be visible from the camera,
taking hysteresis into account for state changes. A begin or end value of 0 will be ignored,
so the visibility range can be open-ended in both directions.

This commit also adds the visibility_parent property to 'Node3D'.
Which defines the visibility parents of the node and its subtree (until
another parent is defined).

Visual instances with a visibility parent will only be visible when the parent, and all of its
ancestors recursively, are hidden because they are closer to the camera than their respective
visibility_range_begin thresholds.

Combining visibility ranges and visibility parents users can set-up a quick HLOD system
that shows high detail meshes when close (i.e buildings, trees) and merged low detail meshes
for far away groups (i.e. cities, woods).

This is a simple example "city":

visdep.mp4

And this is a stress test with 50k of such "cities" (900k meshes in total):

visdep_fly.mp4

Bugsquad edit: This closes godotengine/godot-proposals#692.

@JFonS JFonS added this to the 4.0 milestone May 19, 2021
@JFonS JFonS requested a review from reduz May 19, 2021 15:50
@JFonS JFonS requested review from a team as code owners May 19, 2021 15:50
Copy link
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

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

Looks really good on a quick review. You'll need to do a search and replace to replace all instances of "hysteriesis" with "hysteresis"

doc/classes/GeometryInstance3D.xml Outdated Show resolved Hide resolved
scene/3d/visual_instance_3d.cpp Outdated Show resolved Hide resolved
@fire
Copy link
Member

fire commented May 20, 2021

Are you using the LOD metric that is used by mesh optimizer?

@JFonS
Copy link
Contributor Author

JFonS commented May 20, 2021

Looks really good on a quick review. You'll need to do a search and replace to replace all instances of "hysteriesis" with "hysteresis"

Oops, will do :P

Are you using the LOD metric that is used by mesh optimizer?

No, AFAIK the mesh LOD metric uses the edge lengths and this system has to work on all GeometryInstance3D types. Also, a simple distance check with hysteresis should work just fine for this kind of HLOD.

@Calinou
Copy link
Member

Calinou commented May 20, 2021

Does this visibility range system take the camera FOV into account? I wonder how we can keep using distance ranges while supporting wider/narrower camera FOVs. (Switching to screen coverage metrics would solve this problem automatically, but computing screen coverage has a cost.)

If we want to keep ranges, we could assume that the "default" camera FOV is 75 and use a greater distance multiplier when the FOV is lower (and lower multiplier when the FOV is higher).

Edit: Visibility dependencies aren't FOV-aware, but it can be done by the user if needed. See https://chat.godotengine.org/channel/rendering?msg=ZZE5g87XzQPxpyi5u.

Copy link
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@reduz
Copy link
Member

reduz commented May 30, 2021

I am thinking that as much as it pains me, we should probably change it to a system where the parent has a visibility override over the children and not backwards, else usability will be poor.
This also means storing a list of children in the node, which will make editing more difficult and it may require a special editor. I can work on it I suppose, though I am just unhappy.

@JFonS
Copy link
Contributor Author

JFonS commented Jun 2, 2021

I updated the PR with the following changes:

  • visibility_range_begin and visibility_range_end are disabled if their value is 0. This means I was able to remove the previous visibility_range_enabled property, and visibility checks are internally enabled only when any of the range values is not 0.
  • I changed the visibility_parent behavior so that it only shows it's "children" instances when the camera is too close, while before it would show children whenever the instance was outside of the visibility range (both too far and too close). This means most LOD levels don't have to check for a "range_end" threshold anymore, making the system more user-friendly and faster.

scene/3d/visual_instance_3d.cpp Outdated Show resolved Hide resolved
scene/3d/visual_instance_3d.cpp Outdated Show resolved Hide resolved
@JFonS JFonS force-pushed the vis_deps branch 2 times, most recently from aaf4e31 to 0da3930 Compare June 8, 2021 13:30
@JFonS
Copy link
Contributor Author

JFonS commented Jun 8, 2021

Pushed the latest version with a new way to define visibility dependencies and fixes for all the mentioned issues.

@reduz
Copy link
Member

reduz commented Jun 10, 2021

Looks fantastic, really great job with this!

@JFonS
Copy link
Contributor Author

JFonS commented Jun 10, 2021

I would wait for #48207 to be merged before merging this one. I will take care of the merge conflicts then

This commit adds the following properties to GeometryInstance3D: `visibility_range_begin`,
`visibility_range_begin_margin`, `visibility_range_end`, `visibility_range_end_margin`.

Together they define a range in which the GeometryInstance3D will be visible from the camera,
taking hysteresis into account for state changes. A begin or end value of 0 will be ignored,
so the visibility range can be open-ended in both directions.

This commit also adds the `visibility_parent` property to 'Node3D'.
Which defines the visibility parents of the node and its subtree (until
another parent is defined).

Visual instances with a visibility parent will only be visible when the parent, and all of its
ancestors recursively, are hidden because they are closer to the camera than their respective
`visibility_range_begin` thresholds.

Combining visibility ranges and visibility parents users can set-up a quick HLOD system
that shows high detail meshes when close (i.e buildings, trees) and merged low detail meshes
for far away groups (i.e. cities, woods).
@JFonS
Copy link
Contributor Author

JFonS commented Jun 14, 2021

@akien-mga Rebased!

@akien-mga akien-mga merged commit 6c1445b into godotengine:master Jun 14, 2021
@akien-mga
Copy link
Member

Thanks!

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.

Add support for 3D Level of Detail
6 participants