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

Meshlet continuous LOD #12755

Merged
merged 552 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
552 commits
Select commit Hold shift + click to select a range
20083fa
Parallelise meshlet buffer writes
ricky26 Jan 12, 2024
2283864
Skip some copies during meshlet upload
ricky26 Jan 12, 2024
3f403bb
Merge pull request #17 from ricky26/meshlet
JMS55 Jan 12, 2024
a9f1d9f
Format
JMS55 Jan 12, 2024
3bfa80b
Clippy
JMS55 Jan 12, 2024
c16c3f2
Add TODO
JMS55 Jan 12, 2024
fe3dacb
Move variable out of loop
JMS55 Jan 12, 2024
3c9b361
WIP: Prepass/deferred support
JMS55 Jan 12, 2024
92639e3
Skip prepass draw prepare if only the depth prepass is used
JMS55 Jan 12, 2024
8a4b9aa
WIP: Prepass support
JMS55 Jan 12, 2024
0bd667a
Implement deferred prepass node
JMS55 Jan 12, 2024
cda73dc
Revert example changes comitted by accident
JMS55 Jan 12, 2024
58391d1
Add docs
JMS55 Jan 13, 2024
1d4d89b
Bugfix when using multiple materials
JMS55 Jan 13, 2024
ee2278c
Improve example
JMS55 Jan 13, 2024
737d42d
Fix prepass draws
JMS55 Jan 13, 2024
b04244a
Fix material depth being cleared
JMS55 Jan 13, 2024
ebc68e1
WIP: Prepass/deferred support
JMS55 Jan 13, 2024
bb1490b
Fix imports
JMS55 Jan 13, 2024
25d2943
Finish prepass support
JMS55 Jan 13, 2024
5487522
Revert unintended change
JMS55 Jan 13, 2024
dec0dda
TODO: Remove asset data from buffers on unload
JMS55 Jan 13, 2024
60f2c91
Allow for gaps in PersistentGpuBuffer
JMS55 Jan 14, 2024
e1049d7
Remove outdated doc
JMS55 Jan 14, 2024
0f446fa
Reuse meshlet buffer data where possible
JMS55 Jan 14, 2024
b48daeb
Update crates/bevy_pbr/src/meshlet/material_draw_prepare.rs
JMS55 Jan 14, 2024
109bb4f
Update crates/bevy_pbr/src/meshlet/gpu_scene.rs
JMS55 Jan 14, 2024
11b96e3
Update crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs
JMS55 Jan 14, 2024
1637b6a
Improve docs
JMS55 Jan 14, 2024
f9a8032
Merge commit '4778fbeb65d840eb39bda017fd428ebfc17a1153' into meshlet
JMS55 Jan 14, 2024
f4cb938
Use CameraControllerPlugin
JMS55 Jan 14, 2024
2b665db
Doc lint
JMS55 Jan 14, 2024
684a39f
Replace dragons with bunnies
JMS55 Jan 14, 2024
6bb52d5
Better bunny model
JMS55 Jan 14, 2024
d471820
Fix a bug causing previously visible meshlets to never get marked as …
JMS55 Jan 15, 2024
23207c5
Properly setup view uniform frusta for directional light shadow views
JMS55 Jan 15, 2024
4ddd312
Fix rendering regular meshes when the MeshletPlugin is added
JMS55 Jan 15, 2024
18412d7
Fix deferred compilation on wasm
JMS55 Jan 15, 2024
a03a37e
Add frustums to shadow views for point and spot lights
JMS55 Jan 15, 2024
5f632f1
Merge commit 'aeab690fdb893b6eeb6dbadc646111ea76a5a782' into meshlet
JMS55 Jan 15, 2024
f75dc7a
Update examples/3d/meshlet.rs
JMS55 Jan 15, 2024
932b34f
Merge commit 'ee9a1503edb6ff72cc69514c6336d9f624f0d600' into meshlet
JMS55 Jan 15, 2024
91fd217
Add view instance visibility buffers to gpu scene
atlv24 Jan 16, 2024
ec11c7a
Merge commit 'c9e1fcdb355b049fa3c3df8cb1cd1f4343f1b9d1' into meshlet
JMS55 Jan 18, 2024
9db1a96
Fix rebase lighting
JMS55 Jan 18, 2024
ea38623
Use a single 3d dispatch for write_index_buffer
JMS55 Jan 18, 2024
07bac3c
Remove redundant code
JMS55 Jan 18, 2024
d2903ac
Add TODO
JMS55 Jan 18, 2024
2a6e022
Try to fix occlusion culling (does not seem to be working still)
JMS55 Jan 18, 2024
62d8063
Fix occlusion culling and add meshlet bounding sphere debug viewer
atlv24 Jan 18, 2024
3d96a40
Account for scale
atlv24 Jan 18, 2024
54ac8bb
Merge pull request #22 from rodolphito/meshlet-debug
JMS55 Jan 18, 2024
3d6a7d3
Fix occlusion culling fully
JMS55 Jan 18, 2024
a0f5c6b
Cleanup example
JMS55 Jan 18, 2024
a5cafe3
Improve docs (note limitations)
JMS55 Jan 18, 2024
7979367
Misc wording
JMS55 Jan 18, 2024
2a21ed9
Clippy
JMS55 Jan 18, 2024
e6faae6
Remove rayon
JMS55 Jan 18, 2024
e0b7bf2
Add floor to example
JMS55 Jan 18, 2024
726370a
Fix doc
JMS55 Jan 18, 2024
d0789ae
Merge commit '056b006d4eade8f1bf75e735ed5eda33d9505c9e' into meshlet
JMS55 Jan 18, 2024
4dcc424
Fix occlusion culling in orthographic views
atlv24 Jan 19, 2024
2a5c800
Merge pull request #23 from rodolphito/meshlet-orthographic
JMS55 Jan 19, 2024
ddfbe8a
Misc cleanup
JMS55 Jan 19, 2024
eb4967b
Merge remote-tracking branch 'jasmine/meshlet' into meshlet
atlv24 Jan 19, 2024
fd26948
Misc format
JMS55 Jan 19, 2024
7831a97
Fix initialization
atlv24 Jan 19, 2024
e11b9b0
Add bindings and cull instances
atlv24 Jan 19, 2024
633137d
resize preview
atlv24 Jan 19, 2024
3284621
Merge remote-tracking branch 'jasmine/meshlet' into meshlet
atlv24 Jan 19, 2024
c3b4d34
Move renderlayers/notshadowcaster out to prepare resources
atlv24 Jan 20, 2024
76a9a62
Cleanup
atlv24 Jan 20, 2024
54070b9
better preview
atlv24 Jan 20, 2024
683a4e1
Feedback address
atlv24 Jan 20, 2024
6e20432
Merge pull request #19 from rodolphito/meshlet
JMS55 Jan 20, 2024
f380cb4
Misc
JMS55 Jan 20, 2024
ac5ce53
Remove push constant usage
JMS55 Jan 20, 2024
086ed77
Fix typos
JMS55 Jan 20, 2024
1250949
Merge commit '63eb151619f23b21384cc28e9e11e488c01c4fb9' into meshlet
JMS55 Jan 20, 2024
19e46c3
Fix doc
JMS55 Jan 20, 2024
6c8b8bf
Fix deferred rendering
JMS55 Jan 20, 2024
dd0ec04
Merge branch 'main' into meshlet
JMS55 Jan 20, 2024
67a0bc5
Fix meshlet normal prepass
JMS55 Jan 21, 2024
6e72360
Use crates.io version of meshopt, rename meshopt feature
JMS55 Jan 24, 2024
dc5c57e
Merge commit '02bf4efe64f2d10c8063edc760303e67e9b99e19' into meshlet
JMS55 Jan 24, 2024
ded44f3
Fix rebase
JMS55 Jan 24, 2024
ea39e34
Fix example
JMS55 Jan 24, 2024
fa75dd2
Improve shadows and docs
atlv24 Jan 25, 2024
6bbb428
Improve docs
atlv24 Jan 25, 2024
93fed23
Fix import
atlv24 Jan 25, 2024
ac89611
Merge pull request #24 from rodolphito/meshlet-docs
JMS55 Jan 26, 2024
2249e00
Merge commit '35ac1b152ee1b2c7b2930f67d93be0db6f395b47' into meshlet
JMS55 Jan 26, 2024
1cdd044
Fix type name
JMS55 Jan 26, 2024
16ff589
More fixes
JMS55 Jan 26, 2024
0463f47
Move to an experimental module
JMS55 Jan 26, 2024
084b1a2
Misc doc tweaks
JMS55 Jan 26, 2024
48d5c89
Merge commit '886a2560d24ac248776eea11afabaccfbafa58f4' into meshlet
JMS55 Jan 27, 2024
a0ba8d1
Add some more docs
JMS55 Jan 28, 2024
6328d03
Support modified assets (unlikely that this would ever be used though…
JMS55 Jan 28, 2024
98d375d
Merge commit 'dad379cdca45c31a9b6888f58e6950222aa6842a' into meshlet
JMS55 Jan 28, 2024
c8711bf
Merge commit 'e0778bf407631f9ae0f1e7326bb63e98d0e6fe87' into meshlet
JMS55 Feb 18, 2024
6fd9dc2
Replace deprecated shape API
JMS55 Feb 18, 2024
a22848e
Merge commit 'dc696c0e11515c1c767d4855e545c4f1485b964a' into meshlet
JMS55 Feb 24, 2024
d961c94
Fix rebase
JMS55 Feb 24, 2024
baa8318
Fix meshlets
atlv24 Feb 25, 2024
6a845d7
Merge branch 'main' into meshlet-rebase
atlv24 Feb 25, 2024
7a4f6ca
LegacyColor
atlv24 Feb 25, 2024
4f8cbda
Merge pull request #25 from rodolphito/meshlet-rebase
JMS55 Feb 25, 2024
83debc4
Add comments to clarify shader dispatch sizes and bindings
JMS55 Feb 25, 2024
d33aa85
Merge commit '557e582ec55f325256011ee6e39e97a3d44b2fc3' into meshlet
JMS55 Feb 28, 2024
9e7655a
Fix typo
JMS55 Feb 28, 2024
52eedf2
Fix another typo
JMS55 Feb 28, 2024
d7eb81c
Docs
JMS55 Feb 28, 2024
81ce951
Doc
JMS55 Feb 28, 2024
3ef551a
Fix doc links
JMS55 Feb 29, 2024
474bae2
Fix more doc links
JMS55 Feb 29, 2024
21786e2
Merge commit 'f418de8eb66d0bf1bf42903f8f713167280a3491' into meshlet
JMS55 Feb 29, 2024
a7e7930
Rename direction type
JMS55 Feb 29, 2024
afbd441
Rename thread_id -> cluster_id
JMS55 Feb 29, 2024
8004df0
Example disclaimer
JMS55 Feb 29, 2024
4a69f8a
Update example description
JMS55 Feb 29, 2024
82cb1d8
Doc tweaks
JMS55 Feb 29, 2024
69184bf
Add another doc link
JMS55 Feb 29, 2024
0e7874d
Cleanup persistent_buffer_impls magic numbers
JMS55 Feb 29, 2024
d7fd5d4
Add some more comments
JMS55 Feb 29, 2024
096ea24
Add misc comments
JMS55 Feb 29, 2024
97e2a50
Silence clippy
JMS55 Feb 29, 2024
8db797f
Merge commit '499c978176435efaaf8ccfe3a1141efadfd340eb' into meshlet
JMS55 Mar 1, 2024
182fb8f
Use new color types
JMS55 Mar 1, 2024
b08e45f
Reformat safety doc
JMS55 Mar 1, 2024
12e982e
Use new color API in example
JMS55 Mar 1, 2024
a903873
Merge commit '0746b8eb4c811b473807dfd81091d191f5bcf828' into meshlet
JMS55 Mar 6, 2024
2916dd3
Fix rebase
JMS55 Mar 6, 2024
2f1b399
Fix rebase
JMS55 Mar 6, 2024
24fe534
Misc
JMS55 Mar 6, 2024
c687e59
Merge commit 'a1974a473809c2c6c31fad08174898c220d777bd' into meshlet
JMS55 Mar 7, 2024
79cbf4c
WIP LOD building
JMS55 Mar 7, 2024
3e32004
Small fix
JMS55 Mar 7, 2024
a3187da
Remove allocation for simplification_queue
JMS55 Mar 7, 2024
7d0eb4a
Switch to released metis
JMS55 Mar 7, 2024
bfa4754
Revert "Switch to released metis"
JMS55 Mar 7, 2024
4fc46b9
Fix rebase
JMS55 Mar 7, 2024
328edcd
Merge commit '52e3f2007b54f6be215e59e74aaf3d30b3dad67c' into meshlet
JMS55 Mar 8, 2024
99b18d5
Fix import of thiserror
JMS55 Mar 8, 2024
0c06cd9
Merge commit '99b18d5e789276707fde80e80bda943c08610eb5' into meshlet-…
JMS55 Mar 9, 2024
cf236fe
Fix rebase
JMS55 Mar 9, 2024
7d67997
Fix check
JMS55 Mar 9, 2024
928d809
Merge commit '7d6799758a72ec6b54501614a83b7505d5b781b3' into meshlet-…
JMS55 Mar 9, 2024
25b3abc
Fix simplify code
JMS55 Mar 9, 2024
8f9d54a
Fix meshlet grouping
JMS55 Mar 9, 2024
27773a1
Fix meshlet edge set
JMS55 Mar 9, 2024
c768471
Fix bug with meshlets_slice
JMS55 Mar 10, 2024
be03224
Merge commit '1b3c2b0fed4821d2a8a7554330310ae7f675373d' into meshlet
JMS55 Mar 10, 2024
f146345
Merge commit 'be03224be73b652b6c95d8b3109d3964189ccec8' into meshlet-…
JMS55 Mar 10, 2024
de4cf86
Use metis from crates.io
JMS55 Mar 11, 2024
9680e1b
Merge commit 'c7298599ee11b1f788a248ccd17ccbbaa5a9abb1' into meshlet
JMS55 Mar 12, 2024
0f4de29
Fix normal map sampling
JMS55 Mar 12, 2024
60af7da
Misc refactor
JMS55 Mar 12, 2024
8ac2e94
[WIP] Switch to non-indexed draw buffer
JMS55 Mar 13, 2024
0a7f76c
Misc fix
JMS55 Mar 13, 2024
6be2f94
Clarify comment
JMS55 Mar 13, 2024
a6f8f62
Fix shader
JMS55 Mar 14, 2024
3fc104c
Update asset total_meshlet_triangles
JMS55 Mar 15, 2024
bb77e5a
Merge commit '16fb995697f93d48df565281a9d615606b4b3082' into meshlet
JMS55 Mar 15, 2024
edccb65
Merge commit '1323de7cd74ba7a6fe801e0fa47c357b7760b049' into meshlet
JMS55 Mar 16, 2024
cb58dde
Import rand_f
JMS55 Mar 16, 2024
c7521da
Merge branch 'meshlet' into meshlet-lods
JMS55 Mar 16, 2024
c1605c0
Use real mesh indices for meshlet edge sharing
JMS55 Mar 17, 2024
0fa362d
Prevent infinite LOD building
JMS55 Mar 17, 2024
c3c774f
Cleanup code a bit
JMS55 Mar 17, 2024
36787dc
Merge commit '737b719dda79e15aa70b3a390c871070519f34e0' into meshlet
JMS55 Mar 17, 2024
bdc87f1
Add warning on the material trait methods
JMS55 Mar 18, 2024
8510640
Add warning to example
JMS55 Mar 18, 2024
7eb151c
Update crates/bevy_pbr/src/material.rs
JMS55 Mar 18, 2024
b13b324
Update crates/bevy_pbr/src/material.rs
JMS55 Mar 18, 2024
a0b2bbf
Update crates/bevy_pbr/src/material.rs
JMS55 Mar 18, 2024
c5a0565
Save error metrics when building the asset
JMS55 Mar 19, 2024
6cbad7d
Bind lod_errors buffer
JMS55 Mar 19, 2024
bc8d2ca
WIP: LOD culling
JMS55 Mar 19, 2024
f21f38b
WIP: Add parent info to each cluster
JMS55 Mar 20, 2024
9a1e927
WIP: More parent LOD work
JMS55 Mar 20, 2024
3090eba
More WIP
JMS55 Mar 20, 2024
a7055ee
WIP: Finish (hopefully) the from_mesh part of LOD'ing
JMS55 Mar 20, 2024
cc24dea
Misc docs
JMS55 Mar 20, 2024
3655e68
Fixes
JMS55 Mar 20, 2024
da5b4b4
Extremely WIP runtime LOD selection
JMS55 Mar 21, 2024
b22d53d
Cleanup culling code
JMS55 Mar 21, 2024
e6299f2
Misc rename
JMS55 Mar 21, 2024
68a04b0
Add lod_error_is_imperceptible reference link
JMS55 Mar 21, 2024
9c58cf8
Fix default parent error
JMS55 Mar 22, 2024
e13cc32
Fix wrong LOD decision
JMS55 Mar 22, 2024
9d3a4a9
Revert "Fix wrong LOD decision"
JMS55 Mar 22, 2024
cdd83cb
Merge commit '67cc605e9ff1f7b8d059e7bed32c76732e02d8b5' into meshlet
JMS55 Mar 23, 2024
78dec88
Rename indirect draw buffer
JMS55 Mar 23, 2024
8636e82
Gate meshlets behind a feature (kinda ugly)
JMS55 Mar 23, 2024
f27af6e
Use async asset loader/saver
JMS55 Mar 23, 2024
ec4d06c
Merge commit 'f27af6e99c103bb237fc77b75920633bd7788967' into meshlet-…
JMS55 Mar 23, 2024
898f527
Regen feature docs
JMS55 Mar 23, 2024
0c2275c
Merge commit '898f5279fa3bef9fd4b3238a53c027b6ef3b0f56' into meshlet-…
JMS55 Mar 23, 2024
c96f454
Properly do LOD selection (error metric not yet accurate)
JMS55 Mar 24, 2024
975345c
Better error metric (still slightly noticable, but a lot better)
JMS55 Mar 24, 2024
f0af112
Update meshlet example
JMS55 Mar 24, 2024
57ace17
Early submission for GPU data uploads
JMS55 Mar 24, 2024
f5b7f53
Fix typo in comment
JMS55 Mar 24, 2024
c7eaa58
Merge commit 'e6b5f0574eaa11ca5d310568ca746694819a0fad' into meshlet-…
JMS55 Mar 26, 2024
a0de18a
Misc
JMS55 Mar 26, 2024
37a0967
Remove unplanned lightmap comment
JMS55 Mar 26, 2024
6f89d65
Add TODO to replace meshopt_simplifyScale with high level bindings
JMS55 Mar 27, 2024
044e330
Allow trivial unsafe block
JMS55 Mar 27, 2024
880677b
Merge commit 'c38e2d037dddd5542d10dda1372fca26e9c917cc' into meshlet-…
JMS55 Mar 27, 2024
26bb38c
Allow unsafe for now
JMS55 Mar 27, 2024
1b7cec2
Fix typo
JMS55 Mar 27, 2024
6fc29ec
Merge commit 'ece6249830660a09d46eea5215fb9c0f0623dd22' into meshlet-…
JMS55 Mar 28, 2024
a52f9e7
Merge commit '5357e15966b7936d1134df44b90f347b0f8e1edb' into meshlet-…
JMS55 Mar 29, 2024
3a3d861
Merge commit '01649f13e2d7891573e3f128b27848d286536a89' into meshlet-…
JMS55 Mar 31, 2024
32d1016
Make meshlet_processor feature depend on meshlet feature
JMS55 Mar 31, 2024
113f52c
Add lz4_flex block compression
JMS55 Apr 1, 2024
20c28ac
Switch asset version to 0 while in beta
JMS55 Apr 1, 2024
e910274
Fix CI due to unsafe code lint
JMS55 Apr 2, 2024
f59bcbe
Improvements to LOD building
JMS55 Apr 2, 2024
7580149
Error message tweak
JMS55 Apr 2, 2024
8533e82
Use lz4 frame
JMS55 Apr 2, 2024
9725908
Remove unused import
JMS55 Apr 2, 2024
6978cc7
Update meshopt bindings and remove unsafe
JMS55 Apr 3, 2024
971d941
Misc LOD improvements
JMS55 Apr 3, 2024
d8f57c2
New cumulative error method
JMS55 Apr 3, 2024
8f20363
Make error messages present tense
JMS55 Apr 3, 2024
3f31d62
Optimize meshlets
JMS55 Apr 3, 2024
0037c70
Misc CI fixes
JMS55 Apr 3, 2024
529e630
Feature-gate missed dependencies
JMS55 Apr 3, 2024
dbc1edd
Regenerate bunny asset
JMS55 Apr 3, 2024
f774cbf
Another CI fix
JMS55 Apr 3, 2024
504e5a4
Merge commit 'f516de456be2b65572de1af6956d52157663b9cc' into meshlet-…
JMS55 Apr 3, 2024
9973a77
Reorder nodes
JMS55 Apr 5, 2024
a5626b0
Misc
JMS55 Apr 5, 2024
6443474
Merge commit '6c485c80e02af686c494fa3b0683b8e82c24e70b' into meshlet-…
JMS55 Apr 7, 2024
98a87c5
Fix unsafe lint
JMS55 Apr 7, 2024
646c5c6
Allow unsafe
JMS55 Apr 7, 2024
caad9c8
Revert "Misc"
JMS55 Apr 9, 2024
e57d12c
Merge commit 'ab7cbfa8fca5c17481dac5ab6b4921bd00910e89' into meshlet-…
JMS55 Apr 9, 2024
e456412
Merge branch 'main' into meshlet-lods
JMS55 Apr 10, 2024
7f2fd53
Update crates/bevy_pbr/src/meshlet/from_mesh.rs
JMS55 Apr 10, 2024
cf7d3a9
Fix error tense
JMS55 Apr 10, 2024
48026f2
Merge branch 'main' into meshlet-lods
JMS55 Apr 10, 2024
73fe48e
Merge commit '0256dacba47d697c7ae391a22f121c74de60c2b5' into meshlet-…
JMS55 Apr 14, 2024
865c9d3
Merge commit 'cae07ef56a932ce598d6aa1656f72734c9e7ac27' into meshlet-…
JMS55 Apr 16, 2024
f3dde54
Small doc note
JMS55 Apr 17, 2024
0e5ee9f
Merge commit '831616662297b1586506a43fa3eefc75602bc31f' into meshlet-…
JMS55 Apr 19, 2024
fb0a669
Merge commit '13cac2eeff7e3c4da7ae636ba3766f59b4e343d0' into meshlet-…
JMS55 Apr 21, 2024
81bda63
Remove bunny asset in favor of downloading
JMS55 Apr 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified assets/models/bunny.meshlet_mesh
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think you will need to change this more? Storing binary files in git and having history of them isn't the nicest thing so if we could avoid it, that would be good. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, it will definitely change a couple more times... Storing it externally also sucks though as then you can't run the example easily... Idk what we should do.

Copy link
Contributor

@atlv24 atlv24 Apr 18, 2024

Choose a reason for hiding this comment

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

It will almost certainly change again, the format is not bit packed yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I get Gltf->MeshletMesh asset preprocessing in, we can ship the repo with the GLTF file, and just have users convert it as part of the example. That way we won't have to worry about the MeshletMesh asset changing. But that's a good bit off, I don't want to block on that.

Copy link
Contributor

Choose a reason for hiding this comment

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

@bevyengine/maintainer-team any thoughts on this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Just to note as it happened on Discord - it was decided that hosting the file out of tree would be better, and prompting the user to download it. The reason is that binary files that are modified and committed to the repository will have all versions in git history and the only way to remove them is to rewrite the git history.”, which isn’t nice. But also, rewriting git history breaks all open PRs and branches.

Binary file not shown.
27 changes: 20 additions & 7 deletions crates/bevy_pbr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ shader_format_glsl = ["bevy_render/shader_format_glsl"]
trace = ["bevy_render/trace"]
ios_simulator = ["bevy_render/ios_simulator"]
# Enables the meshlet renderer for dense high-poly scenes (experimental)
meshlet = []
meshlet = [
"dep:lz4_flex",
"dep:serde",
"dep:bincode",
"dep:thiserror",
"dep:range-alloc",
]
# Enables processing meshes into meshlet meshes
meshlet_processor = ["dep:meshopt", "dep:thiserror"]
meshlet_processor = ["meshlet", "dep:meshopt", "dep:metis", "dep:itertools"]

[dependencies]
# bevy
Expand All @@ -37,18 +43,25 @@ bevy_utils = { path = "../bevy_utils", version = "0.14.0-dev" }
bevy_window = { path = "../bevy_window", version = "0.14.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.14.0-dev" }


# other
meshopt = { version = "0.2", optional = true }
thiserror = { version = "1", optional = true }
bitflags = "2.3"
fixedbitset = "0.5"
# meshlet
lz4_flex = { version = "0.11", default-features = false, features = [
"frame",
], optional = true }
serde = { version = "1", features = ["derive", "rc"], optional = true }
bincode = { version = "1", optional = true }
thiserror = { version = "1", optional = true }
range-alloc = { version = "0.1", optional = true }
meshopt = { version = "0.2", optional = true }
metis = { version = "0.2", optional = true }
itertools = { version = "0.12", optional = true }
# direct dependency required for derive macro
bytemuck = { version = "1", features = ["derive"] }
radsort = "0.1"
smallvec = "1.6"
serde = { version = "1", features = ["derive", "rc"] }
bincode = "1"
range-alloc = "0.1"
nonmax = "0.5"
static_assertions = "1"

Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_pbr/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// FIXME(3492): remove once docs are ready
#![allow(missing_docs)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![forbid(unsafe_code)]
#![allow(unsafe_code)]
JMS55 marked this conversation as resolved.
Show resolved Hide resolved
#![doc(
html_logo_url = "https://bevyengine.org/assets/icon.png",
html_favicon_url = "https://bevyengine.org/assets/icon.png"
Expand Down
73 changes: 62 additions & 11 deletions crates/bevy_pbr/src/meshlet/asset.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
use bevy_asset::{
io::{Reader, Writer},
io::{AsyncReadAndSeek, Reader, Writer},
saver::{AssetSaver, SavedAsset},
Asset, AssetLoader, AsyncReadExt, AsyncWriteExt, LoadContext,
};
use bevy_math::Vec3;
use bevy_reflect::TypePath;
use bytemuck::{Pod, Zeroable};
use lz4_flex::frame::{FrameDecoder, FrameEncoder};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::{io::Cursor, sync::Arc};

/// The current version of the [`MeshletMesh`] asset format.
pub const MESHLET_MESH_ASSET_VERSION: u64 = 0;

/// A mesh that has been pre-processed into multiple small clusters of triangles called meshlets.
///
Expand All @@ -25,8 +29,8 @@ use std::sync::Arc;
/// See also [`super::MaterialMeshletMeshBundle`] and [`super::MeshletPlugin`].
#[derive(Asset, TypePath, Serialize, Deserialize, Clone)]
pub struct MeshletMesh {
/// The total amount of triangles summed across all meshlets in the mesh.
pub total_meshlet_triangles: u64,
/// The total amount of triangles summed across all LOD 0 meshlets in the mesh.
pub worst_case_meshlet_triangles: u64,
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe max_meshlet_triangles?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I personally feel that that's less clear. Up to maintainers.

Copy link
Contributor

Choose a reason for hiding this comment

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

i prefer keeping it as is

/// Raw vertex data bytes for the overall mesh.
pub vertex_data: Arc<[u8]>,
/// Indices into `vertex_data`.
Expand All @@ -35,8 +39,8 @@ pub struct MeshletMesh {
pub indices: Arc<[u8]>,
/// The list of meshlets making up this mesh.
pub meshlets: Arc<[Meshlet]>,
/// A list of spherical bounding volumes, 1 per meshlet.
pub meshlet_bounding_spheres: Arc<[MeshletBoundingSphere]>,
/// Spherical bounding volumes.
pub bounding_spheres: Arc<[MeshletBoundingSpheres]>,
}

/// A single meshlet within a [`MeshletMesh`].
Expand All @@ -51,7 +55,19 @@ pub struct Meshlet {
pub triangle_count: u32,
}

/// A spherical bounding volume used for culling a [`Meshlet`].
/// Bounding spheres used for culling and choosing level of detail for a [`Meshlet`].
#[derive(Serialize, Deserialize, Copy, Clone, Pod, Zeroable)]
#[repr(C)]
pub struct MeshletBoundingSpheres {
/// The bounding sphere used for frustum and occlusion culling for this meshlet.
pub self_culling: MeshletBoundingSphere,
/// The bounding sphere used for determining if this meshlet is at the correct level of detail for a given view.
pub self_lod: MeshletBoundingSphere,
/// The bounding sphere used for determining if this meshlet's parent is at the correct level of detail for a given view.
pub parent_lod: MeshletBoundingSphere,
}

/// A spherical bounding volume used for a [`Meshlet`].
#[derive(Serialize, Deserialize, Copy, Clone, Pod, Zeroable)]
#[repr(C)]
pub struct MeshletBoundingSphere {
Expand All @@ -65,17 +81,24 @@ pub struct MeshletMeshSaverLoad;
impl AssetLoader for MeshletMeshSaverLoad {
type Asset = MeshletMesh;
type Settings = ();
type Error = bincode::Error;
type Error = MeshletMeshSaveOrLoadError;

async fn load<'a>(
&'a self,
reader: &'a mut Reader<'_>,
_settings: &'a Self::Settings,
_load_context: &'a mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
let version = read_u64(reader).await?;
if version != MESHLET_MESH_ASSET_VERSION {
return Err(MeshletMeshSaveOrLoadError::WrongVersion { found: version });
}

let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
bincode::deserialize(&bytes)
let asset = bincode::deserialize_from(FrameDecoder::new(Cursor::new(bytes)))?;

Ok(asset)
}

fn extensions(&self) -> &[&str] {
Expand All @@ -87,16 +110,44 @@ impl AssetSaver for MeshletMeshSaverLoad {
type Asset = MeshletMesh;
type Settings = ();
type OutputLoader = Self;
type Error = bincode::Error;
type Error = MeshletMeshSaveOrLoadError;

async fn save<'a>(
&'a self,
writer: &'a mut Writer,
asset: SavedAsset<'a, Self::Asset>,
_settings: &'a Self::Settings,
) -> Result<(), Self::Error> {
let bytes = bincode::serialize(asset.get())?;
writer
.write_all(&MESHLET_MESH_ASSET_VERSION.to_le_bytes())
.await?;

let mut bytes = Vec::new();
let mut sync_writer = FrameEncoder::new(&mut bytes);
bincode::serialize_into(&mut sync_writer, asset.get())?;
sync_writer.finish()?;
writer.write_all(&bytes).await?;

Ok(())
}
}

#[derive(thiserror::Error, Debug)]
pub enum MeshletMeshSaveOrLoadError {
JMS55 marked this conversation as resolved.
Show resolved Hide resolved
#[error("expected asset version {MESHLET_MESH_ASSET_VERSION} but found version {found}")]
WrongVersion { found: u64 },
#[error("failed to serialize or deserialize asset data")]
SerializationOrDeserialization(#[from] bincode::Error),
#[error("failed to compress or decompress asset data")]
CompressionOrDecompression(#[from] lz4_flex::frame::Error),
#[error("failed to read or write asset data")]
Io(#[from] std::io::Error),
}

async fn read_u64(
reader: &mut (dyn AsyncReadAndSeek + Sync + Send + Unpin),
) -> Result<u64, bincode::Error> {
let mut bytes = [0u8; 8];
reader.read_exact(&mut bytes).await?;
Ok(u64::from_le_bytes(bytes))
}
47 changes: 38 additions & 9 deletions crates/bevy_pbr/src/meshlet/cull_meshlets.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,34 @@
@compute
@workgroup_size(128, 1, 1) // 128 threads per workgroup, 1 instanced meshlet per thread
fn cull_meshlets(@builtin(global_invocation_id) cluster_id: vec3<u32>) {
// Fetch the instanced meshlet data
// Fetch the instance data and check for instance culling
if cluster_id.x >= arrayLength(&meshlet_thread_meshlet_ids) { return; }
let instance_id = meshlet_thread_instance_ids[cluster_id.x];
if should_cull_instance(instance_id) {
return;
}

// Fetch other meshlet data
let meshlet_id = meshlet_thread_meshlet_ids[cluster_id.x];
let bounding_sphere = meshlet_bounding_spheres[meshlet_id];
let instance_uniform = meshlet_instance_uniforms[instance_id];
let model = affine3_to_square(instance_uniform.model);
let model_scale = max(length(model[0]), max(length(model[1]), length(model[2])));
let bounding_sphere_center = model * vec4(bounding_sphere.center, 1.0);
let bounding_sphere_radius = model_scale * bounding_sphere.radius;
let bounding_spheres = meshlet_bounding_spheres[meshlet_id];

// Calculate view-space LOD bounding sphere for the meshlet
let lod_bounding_sphere_center = model * vec4(bounding_spheres.self_lod.center, 1.0);
let lod_bounding_sphere_radius = model_scale * bounding_spheres.self_lod.radius;
let lod_bounding_sphere_center_view_space = (view.inverse_view * vec4(lod_bounding_sphere_center.xyz, 1.0)).xyz;

// Calculate view-space LOD bounding sphere for the meshlet's parent
let parent_lod_bounding_sphere_center = model * vec4(bounding_spheres.parent_lod.center, 1.0);
let parent_lod_bounding_sphere_radius = model_scale * bounding_spheres.parent_lod.radius;
let parent_lod_bounding_sphere_center_view_space = (view.inverse_view * vec4(parent_lod_bounding_sphere_center.xyz, 1.0)).xyz;

// Check LOD cut (meshlet error imperceptible, and parent error not imperceptible)
let lod_is_ok = lod_error_is_imperceptible(lod_bounding_sphere_center_view_space, lod_bounding_sphere_radius);
let parent_lod_is_ok = lod_error_is_imperceptible(parent_lod_bounding_sphere_center_view_space, parent_lod_bounding_sphere_radius);
if !lod_is_ok || parent_lod_is_ok { return; }

// In the first pass, operate only on the clusters visible last frame. In the second pass, operate on all clusters.
#ifdef MESHLET_SECOND_CULLING_PASS
Expand All @@ -42,18 +57,22 @@ fn cull_meshlets(@builtin(global_invocation_id) cluster_id: vec3<u32>) {
if !meshlet_visible { return; }
#endif

// Calculate world-space culling bounding sphere for the cluster
let culling_bounding_sphere_center = model * vec4(bounding_spheres.self_culling.center, 1.0);
let culling_bounding_sphere_radius = model_scale * bounding_spheres.self_culling.radius;

// Frustum culling
// TODO: Faster method from https://vkguide.dev/docs/gpudriven/compute_culling/#frustum-culling-function
for (var i = 0u; i < 6u; i++) {
if !meshlet_visible { break; }
meshlet_visible &= dot(view.frustum[i], bounding_sphere_center) > -bounding_sphere_radius;
meshlet_visible &= dot(view.frustum[i], culling_bounding_sphere_center) > -culling_bounding_sphere_radius;
}

#ifdef MESHLET_SECOND_CULLING_PASS
// In the second culling pass, cull against the depth pyramid generated from the first pass
if meshlet_visible {
let bounding_sphere_center_view_space = (view.inverse_view * vec4(bounding_sphere_center.xyz, 1.0)).xyz;
let aabb = project_view_space_sphere_to_screen_space_aabb(bounding_sphere_center_view_space, bounding_sphere_radius);
let culling_bounding_sphere_center_view_space = (view.inverse_view * vec4(culling_bounding_sphere_center.xyz, 1.0)).xyz;
let aabb = project_view_space_sphere_to_screen_space_aabb(culling_bounding_sphere_center_view_space, culling_bounding_sphere_radius);

// Halve the AABB size because the first depth mip resampling pass cut the full screen resolution into a power of two conservatively
let depth_pyramid_size_mip_0 = vec2<f32>(textureDimensions(depth_pyramid, 0)) * 0.5;
Expand All @@ -71,11 +90,11 @@ fn cull_meshlets(@builtin(global_invocation_id) cluster_id: vec3<u32>) {
let occluder_depth = min(min(depth_quad_a, depth_quad_b), min(depth_quad_c, depth_quad_d));
if view.projection[3][3] == 1.0 {
// Orthographic
let sphere_depth = view.projection[3][2] + (bounding_sphere_center_view_space.z + bounding_sphere_radius) * view.projection[2][2];
let sphere_depth = view.projection[3][2] + (culling_bounding_sphere_center_view_space.z + culling_bounding_sphere_radius) * view.projection[2][2];
meshlet_visible &= sphere_depth >= occluder_depth;
} else {
// Perspective
let sphere_depth = -view.projection[3][2] / (bounding_sphere_center_view_space.z + bounding_sphere_radius);
let sphere_depth = -view.projection[3][2] / (culling_bounding_sphere_center_view_space.z + culling_bounding_sphere_radius);
meshlet_visible &= sphere_depth >= occluder_depth;
}
}
Expand All @@ -86,6 +105,16 @@ fn cull_meshlets(@builtin(global_invocation_id) cluster_id: vec3<u32>) {
atomicOr(&meshlet_occlusion[cluster_id.x / 32u], occlusion_bit);
}

// https://stackoverflow.com/questions/21648630/radius-of-projected-sphere-in-screen-space/21649403#21649403
fn lod_error_is_imperceptible(cp: vec3<f32>, r: f32) -> bool {
let d2 = dot(cp, cp);
let r2 = r * r;
let sphere_diameter_uv = view.projection[0][0] * r / sqrt(d2 - r2);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
let sphere_diameter_uv = view.projection[0][0] * r / sqrt(d2 - r2);
let sphere_diameter_uv = view.projection[0][0] * r * inverseSqrt(d2 - r2);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The spec says inverseSqrt() does not work if e <= 0. Need to think if this is an issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

i dont think sqrt is guaranteed to work for e <= 0 either. I'd just slab an abs or max 0 on it if its a worry, being explicit about edge case behavior intent is valuable and saturating/clamping is often free in gpus

let view_size = f32(max(view.viewport.z, view.viewport.w));
let sphere_diameter_pixels = sphere_diameter_uv * view_size;
return sphere_diameter_pixels < 1.0;
}

// https://zeux.io/2023/01/12/approximate-projected-bounds
fn project_view_space_sphere_to_screen_space_aabb(cp: vec3<f32>, r: f32) -> vec4<f32> {
let inv_width = view.projection[0][0] * 0.5;
Expand Down
Loading