switch to noise lib that works on arm neon (apple)
This commit is contained in:
475
Cargo.lock
generated
475
Cargo.lock
generated
@@ -31,6 +31,15 @@ dependencies = [
|
|||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
version = "0.2.18"
|
version = "0.2.18"
|
||||||
@@ -73,6 +82,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ansi_term"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "approx"
|
name = "approx"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@@ -100,13 +118,22 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
|
checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ash"
|
||||||
|
version = "0.37.3+1.3.251"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a"
|
||||||
|
dependencies = [
|
||||||
|
"libloading 0.7.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ash"
|
name = "ash"
|
||||||
version = "0.38.0+1.3.281"
|
version = "0.38.0+1.3.281"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f"
|
checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libloading",
|
"libloading 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -146,6 +173,17 @@ version = "1.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi 0.1.19",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -286,6 +324,30 @@ dependencies = [
|
|||||||
"syn 2.0.77",
|
"syn 2.0.77",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bindgen"
|
||||||
|
version = "0.55.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75b13ce559e6433d360c26305643803cb52cfbabbc2b9c47ce04a58493dfb443"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"cexpr",
|
||||||
|
"cfg-if 0.1.10",
|
||||||
|
"clang-sys",
|
||||||
|
"clap",
|
||||||
|
"env_logger",
|
||||||
|
"lazy_static",
|
||||||
|
"lazycell",
|
||||||
|
"log",
|
||||||
|
"peeking_take_while",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"rustc-hash 1.1.0",
|
||||||
|
"shlex 0.1.1",
|
||||||
|
"which",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit-set"
|
name = "bit-set"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@@ -411,7 +473,7 @@ checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
"shlex",
|
"shlex 1.3.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -420,6 +482,15 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cexpr"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
@@ -444,6 +515,32 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clang-sys"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||||
|
dependencies = [
|
||||||
|
"glob",
|
||||||
|
"libc",
|
||||||
|
"libloading 0.8.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "2.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||||
|
dependencies = [
|
||||||
|
"ansi_term",
|
||||||
|
"atty",
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"strsim",
|
||||||
|
"textwrap",
|
||||||
|
"unicode-width",
|
||||||
|
"vec_map",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codespan-reporting"
|
name = "codespan-reporting"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
@@ -544,12 +641,27 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-queue"
|
||||||
|
version = "0.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.20"
|
version = "0.8.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crunchy"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cursor-icon"
|
name = "cursor-icon"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -566,7 +678,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "bdbd1f579714e3c809ebd822c81ef148b1ceaeb3d535352afc73fd0c4c6a0017"
|
checksum = "bdbd1f579714e3c809ebd822c81ef148b1ceaeb3d535352afc73fd0c4c6a0017"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"libloading",
|
"libloading 0.8.5",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -582,7 +694,7 @@ version = "0.5.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libloading",
|
"libloading 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -609,6 +721,19 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"humantime",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
"termcolor",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@@ -656,6 +781,25 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastnoise-simd"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d156d53d8fcdad2a9392bbc74fb94a508fdb3c059dff24da748954ffe2308a42"
|
||||||
|
dependencies = [
|
||||||
|
"fastnoise_simd_bindings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastnoise_simd_bindings"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb6813cbacdd6525a31c02a117acc8581f37f104b11ab77e942029f4df994698"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
@@ -760,6 +904,12 @@ version = "0.19.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b8509e6791516e81c1a630d0bd7fbac36d2fa8712a9da8662e716b52d5051ca"
|
checksum = "2b8509e6791516e81c1a630d0bd7fbac36d2fa8712a9da8662e716b52d5051ca"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glob"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glow"
|
name = "glow"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
@@ -833,6 +983,17 @@ dependencies = [
|
|||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "half"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"crunchy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.5"
|
version = "0.14.5"
|
||||||
@@ -853,12 +1014,27 @@ dependencies = [
|
|||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"com",
|
"com",
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
"libloading 0.8.5",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"widestring",
|
"widestring",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@@ -871,6 +1047,15 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||||
|
dependencies = [
|
||||||
|
"quick-error",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ilattice"
|
name = "ilattice"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -890,6 +1075,12 @@ dependencies = [
|
|||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jni"
|
name = "jni"
|
||||||
version = "0.21.1"
|
version = "0.21.1"
|
||||||
@@ -937,7 +1128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76"
|
checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
"libloading 0.8.5",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -947,12 +1138,34 @@ version = "3.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazycell"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.158"
|
version = "0.2.158"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libloading"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
@@ -1048,7 +1261,7 @@ dependencies = [
|
|||||||
"foreign-types",
|
"foreign-types",
|
||||||
"log",
|
"log",
|
||||||
"objc",
|
"objc",
|
||||||
"paste 1.0.15",
|
"paste",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1133,7 +1346,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"ndk-sys 0.6.0+11769913",
|
"ndk-sys 0.6.0+11769913",
|
||||||
"num_enum",
|
"num_enum",
|
||||||
"raw-window-handle",
|
"raw-window-handle 0.6.2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1170,6 +1383,16 @@ dependencies = [
|
|||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "5.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nonmax"
|
name = "nonmax"
|
||||||
version = "0.5.5"
|
version = "0.5.5"
|
||||||
@@ -1239,7 +1462,7 @@ version = "0.7.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate 3.2.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.77",
|
"syn 2.0.77",
|
||||||
@@ -1510,16 +1733,6 @@ dependencies = [
|
|||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "paste"
|
|
||||||
version = "0.1.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
|
|
||||||
dependencies = [
|
|
||||||
"paste-impl",
|
|
||||||
"proc-macro-hack",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.15"
|
version = "1.0.15"
|
||||||
@@ -1527,13 +1740,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste-impl"
|
name = "peeking_take_while"
|
||||||
version = "0.1.18"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
|
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||||
dependencies = [
|
|
||||||
"proc-macro-hack",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
@@ -1591,7 +1801,7 @@ checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"hermit-abi",
|
"hermit-abi 0.4.0",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustix",
|
"rustix",
|
||||||
"tracing",
|
"tracing",
|
||||||
@@ -1619,6 +1829,16 @@ version = "0.3.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
|
checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-crate"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"toml_edit 0.19.15",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "3.2.0"
|
version = "3.2.0"
|
||||||
@@ -1628,12 +1848,6 @@ dependencies = [
|
|||||||
"toml_edit 0.22.20",
|
"toml_edit 0.22.20",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-hack"
|
|
||||||
version = "0.5.20+deprecated"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.86"
|
version = "1.0.86"
|
||||||
@@ -1649,6 +1863,12 @@ version = "1.0.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
|
checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-error"
|
||||||
|
version = "1.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-xml"
|
name = "quick-xml"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
@@ -1703,6 +1923,12 @@ version = "0.1.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab"
|
checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "raw-window-handle"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "raw-window-handle"
|
name = "raw-window-handle"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
@@ -1733,6 +1959,35 @@ dependencies = [
|
|||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.10.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "renderdoc-sys"
|
name = "renderdoc-sys"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -1764,6 +2019,12 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "safe_arch"
|
name = "safe_arch"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
@@ -1827,6 +2088,24 @@ dependencies = [
|
|||||||
"syn 2.0.77",
|
"syn 2.0.77",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.128"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -1842,7 +2121,7 @@ dependencies = [
|
|||||||
"approx",
|
"approx",
|
||||||
"num-complex",
|
"num-complex",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"paste 1.0.15",
|
"paste",
|
||||||
"wide",
|
"wide",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1855,29 +2134,10 @@ dependencies = [
|
|||||||
"approx",
|
"approx",
|
||||||
"num-complex",
|
"num-complex",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"paste 1.0.15",
|
"paste",
|
||||||
"wide",
|
"wide",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "simdeez"
|
|
||||||
version = "1.0.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f6ec898e1be717eee4b54a84ff2fc94ecb5a1b992d4ad148ce30575b45745662"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 0.1.10",
|
|
||||||
"paste 0.1.18",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "simdnoise"
|
|
||||||
version = "3.1.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d9f69a3fa031fc2906ffe27aecc55bdd2c9cb95327c4695ea814a083145fa462"
|
|
||||||
dependencies = [
|
|
||||||
"simdeez",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
@@ -1960,6 +2220,12 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
@@ -1991,6 +2257,15 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.63"
|
version = "1.0.63"
|
||||||
@@ -2052,6 +2327,17 @@ version = "0.6.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.19.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow 0.5.40",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.21.1"
|
version = "0.21.1"
|
||||||
@@ -2145,12 +2431,27 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vec_map"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vk-parse"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "81086c28be67a8759cd80cbb3c8f7b520e0874605fc5eb74d5a1c9c2d1878e79"
|
||||||
|
dependencies = [
|
||||||
|
"xml-rs",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "voxelgame"
|
name = "voxelgame"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -2159,17 +2460,60 @@ dependencies = [
|
|||||||
"bevy_ecs",
|
"bevy_ecs",
|
||||||
"block-mesh",
|
"block-mesh",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
"fastnoise-simd",
|
||||||
"nalgebra",
|
"nalgebra",
|
||||||
"ndarray",
|
"ndarray",
|
||||||
"pollster",
|
"pollster",
|
||||||
"rand",
|
"rand",
|
||||||
"rustc-hash 2.0.0",
|
"rustc-hash 2.0.0",
|
||||||
"simba 0.8.1",
|
"simba 0.8.1",
|
||||||
"simdnoise",
|
"vulkano",
|
||||||
"wgpu",
|
"wgpu",
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vulkano"
|
||||||
|
version = "0.34.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70f4278f76307b3c388679234b397b4f90de29cdba53873c26b624ed82653d75"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"ash 0.37.3+1.3.251",
|
||||||
|
"bytemuck",
|
||||||
|
"core-graphics-types",
|
||||||
|
"crossbeam-queue",
|
||||||
|
"half",
|
||||||
|
"heck",
|
||||||
|
"indexmap",
|
||||||
|
"libloading 0.8.5",
|
||||||
|
"objc",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"raw-window-handle 0.5.2",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"smallvec",
|
||||||
|
"thread_local",
|
||||||
|
"vk-parse",
|
||||||
|
"vulkano-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vulkano-macros"
|
||||||
|
version = "0.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52be622d364272fd77e298e7f68e8547ae66e7687cb86eb85335412cee7e3965"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-crate 1.3.1",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@@ -2406,7 +2750,7 @@ dependencies = [
|
|||||||
"naga",
|
"naga",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"profiling",
|
"profiling",
|
||||||
"raw-window-handle",
|
"raw-window-handle 0.6.2",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@@ -2434,7 +2778,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"profiling",
|
"profiling",
|
||||||
"raw-window-handle",
|
"raw-window-handle 0.6.2",
|
||||||
"rustc-hash 1.1.0",
|
"rustc-hash 1.1.0",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -2450,7 +2794,7 @@ checksum = "f6bbf4b4de8b2a83c0401d9e5ae0080a2792055f25859a02bf9be97952bbed4f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"android_system_properties",
|
"android_system_properties",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"ash",
|
"ash 0.38.0+1.3.281",
|
||||||
"bit-set",
|
"bit-set",
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"block",
|
"block",
|
||||||
@@ -2466,7 +2810,7 @@ dependencies = [
|
|||||||
"js-sys",
|
"js-sys",
|
||||||
"khronos-egl",
|
"khronos-egl",
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
"libloading 0.8.5",
|
||||||
"log",
|
"log",
|
||||||
"metal",
|
"metal",
|
||||||
"naga",
|
"naga",
|
||||||
@@ -2476,7 +2820,7 @@ dependencies = [
|
|||||||
"parking_lot",
|
"parking_lot",
|
||||||
"profiling",
|
"profiling",
|
||||||
"range-alloc",
|
"range-alloc",
|
||||||
"raw-window-handle",
|
"raw-window-handle 0.6.2",
|
||||||
"renderdoc-sys",
|
"renderdoc-sys",
|
||||||
"rustc-hash 1.1.0",
|
"rustc-hash 1.1.0",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
@@ -2498,6 +2842,15 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "3.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wide"
|
name = "wide"
|
||||||
version = "0.7.28"
|
version = "0.7.28"
|
||||||
@@ -2799,7 +3152,7 @@ dependencies = [
|
|||||||
"orbclient",
|
"orbclient",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"raw-window-handle",
|
"raw-window-handle 0.6.2",
|
||||||
"redox_syscall 0.4.1",
|
"redox_syscall 0.4.1",
|
||||||
"rustix",
|
"rustix",
|
||||||
"sctk-adwaita",
|
"sctk-adwaita",
|
||||||
@@ -2860,7 +3213,7 @@ dependencies = [
|
|||||||
"as-raw-xcb-connection",
|
"as-raw-xcb-connection",
|
||||||
"gethostname",
|
"gethostname",
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
"libloading 0.8.5",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix",
|
"rustix",
|
||||||
"x11rb-protocol",
|
"x11rb-protocol",
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ ndarray = "0.15.6"
|
|||||||
pollster = "0.3"
|
pollster = "0.3"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
simba = "0.8.1"
|
simba = "0.8.1"
|
||||||
simdnoise = "3.1.6"
|
|
||||||
wgpu = "22.0.0"
|
wgpu = "22.0.0"
|
||||||
bevy_ecs = "0.13.2"
|
bevy_ecs = "0.13.2"
|
||||||
bevy_derive = "0.13.2"
|
bevy_derive = "0.13.2"
|
||||||
winit = {version="0.30.1", features=["serde"]}
|
winit = {version="0.30.1", features=["serde"]}
|
||||||
block-mesh = "0.2.0"
|
block-mesh = "0.2.0"
|
||||||
rustc-hash = "2.0.0"
|
rustc-hash = "2.0.0"
|
||||||
|
vulkano = "0.34.1"
|
||||||
|
fastnoise-simd = "0.1.1"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ mod camera;
|
|||||||
mod component;
|
mod component;
|
||||||
mod handle_input;
|
mod handle_input;
|
||||||
mod input;
|
mod input;
|
||||||
|
// mod render_vulkan;
|
||||||
pub mod render;
|
pub mod render;
|
||||||
mod rsc;
|
mod rsc;
|
||||||
mod state;
|
mod state;
|
||||||
@@ -66,7 +67,7 @@ impl Client<'_> {
|
|||||||
.expect("Failed to create window"),
|
.expect("Failed to create window"),
|
||||||
);
|
);
|
||||||
|
|
||||||
let renderer = Renderer::spawn(window.clone());
|
let renderer = Renderer::new(window.clone());
|
||||||
world.insert_resource(RenderCommands(Vec::new()));
|
world.insert_resource(RenderCommands(Vec::new()));
|
||||||
|
|
||||||
let state = ClientState::new();
|
let state = ClientState::new();
|
||||||
|
|||||||
@@ -43,20 +43,6 @@ pub struct UpdateGridTransform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Renderer<'a> {
|
impl<'a> Renderer<'a> {
|
||||||
pub fn spawn(window: Arc<Window>) -> Renderer<'a> {
|
|
||||||
let size = window.inner_size();
|
|
||||||
|
|
||||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
|
||||||
backends: wgpu::Backends::PRIMARY,
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
|
|
||||||
let surface = instance
|
|
||||||
.create_surface(window)
|
|
||||||
.expect("Could not create window surface!");
|
|
||||||
Self::new(instance, surface, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_commands(&mut self, commands: Vec<RenderCommand>) {
|
pub fn handle_commands(&mut self, commands: Vec<RenderCommand>) {
|
||||||
let mut new_camera = false;
|
let mut new_camera = false;
|
||||||
for cmd in commands {
|
for cmd in commands {
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
mod command;
|
mod command;
|
||||||
mod util;
|
mod util;
|
||||||
pub mod voxel;
|
pub mod voxel;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub use command::*;
|
pub use command::*;
|
||||||
|
|
||||||
use super::camera::Camera;
|
use super::camera::Camera;
|
||||||
use crate::{client::rsc::CLEAR_COLOR, util::timer::Timer};
|
use crate::client::rsc::CLEAR_COLOR;
|
||||||
use nalgebra::Vector2;
|
use nalgebra::Vector2;
|
||||||
use util::DepthTexture;
|
use util::DepthTexture;
|
||||||
use voxel::VoxelPipeline;
|
use voxel::VoxelPipeline;
|
||||||
use winit::dpi::PhysicalSize;
|
use winit::{dpi::PhysicalSize, window::Window};
|
||||||
|
|
||||||
pub struct Renderer<'a> {
|
pub struct Renderer<'a> {
|
||||||
size: Vector2<u32>,
|
size: Vector2<u32>,
|
||||||
@@ -25,10 +27,19 @@ pub struct Renderer<'a> {
|
|||||||
|
|
||||||
impl<'a> Renderer<'a> {
|
impl<'a> Renderer<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
instance: wgpu::Instance,
|
window: Arc<Window>,
|
||||||
surface: wgpu::Surface<'a>,
|
|
||||||
size: PhysicalSize<u32>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let size = window.inner_size();
|
||||||
|
|
||||||
|
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||||
|
backends: wgpu::Backends::PRIMARY,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
let surface = instance
|
||||||
|
.create_surface(window)
|
||||||
|
.expect("Could not create window surface!");
|
||||||
|
|
||||||
let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
|
let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
|
||||||
power_preference: wgpu::PowerPreference::default(),
|
power_preference: wgpu::PowerPreference::default(),
|
||||||
compatible_surface: Some(&surface),
|
compatible_surface: Some(&surface),
|
||||||
@@ -36,11 +47,16 @@ impl<'a> Renderer<'a> {
|
|||||||
}))
|
}))
|
||||||
.expect("Could not get adapter!");
|
.expect("Could not get adapter!");
|
||||||
|
|
||||||
|
let buf_size = (10u32.pow(9) * 15) / 10;
|
||||||
let (device, queue) = pollster::block_on(adapter.request_device(
|
let (device, queue) = pollster::block_on(adapter.request_device(
|
||||||
&wgpu::DeviceDescriptor {
|
&wgpu::DeviceDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
required_features: wgpu::Features::empty(),
|
required_features: wgpu::Features::empty(),
|
||||||
required_limits: wgpu::Limits::default(),
|
required_limits: wgpu::Limits {
|
||||||
|
max_storage_buffer_binding_size: buf_size,
|
||||||
|
max_buffer_size: buf_size as u64,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
memory_hints: wgpu::MemoryHints::default(),
|
memory_hints: wgpu::MemoryHints::default(),
|
||||||
},
|
},
|
||||||
None, // Trace path
|
None, // Trace path
|
||||||
@@ -160,8 +176,7 @@ impl<'a> Renderer<'a> {
|
|||||||
self.surface.configure(&self.device, &self.config);
|
self.surface.configure(&self.device, &self.config);
|
||||||
self.voxel_pipeline.resize(&self.device, self.size);
|
self.voxel_pipeline.resize(&self.device, self.size);
|
||||||
|
|
||||||
self.depth_texture =
|
self.depth_texture = DepthTexture::init(&self.device, &self.config, "depth_texture");
|
||||||
DepthTexture::init(&self.device, &self.config, "depth_texture");
|
|
||||||
self.voxel_pipeline.update_view(
|
self.voxel_pipeline.update_view(
|
||||||
&self.device,
|
&self.device,
|
||||||
&mut self.encoder,
|
&mut self.encoder,
|
||||||
|
|||||||
53
src/client/render/voxel/ray/voxel/color.rs
Normal file
53
src/client/render/voxel/ray/voxel/color.rs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
use rand::distributions::{Distribution, Standard};
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Zeroable)]
|
||||||
|
pub struct VoxelColor {
|
||||||
|
pub r: u8,
|
||||||
|
pub g: u8,
|
||||||
|
pub b: u8,
|
||||||
|
pub a: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl bytemuck::Pod for VoxelColor {}
|
||||||
|
|
||||||
|
impl VoxelColor {
|
||||||
|
pub fn none() -> Self {
|
||||||
|
Self {
|
||||||
|
r: 0,
|
||||||
|
g: 0,
|
||||||
|
b: 0,
|
||||||
|
a: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn black() -> Self {
|
||||||
|
Self {
|
||||||
|
r: 0,
|
||||||
|
g: 0,
|
||||||
|
b: 0,
|
||||||
|
a: 255,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn white() -> Self {
|
||||||
|
Self {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
a: 255,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn random() -> Self {
|
||||||
|
rand::random()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Distribution<VoxelColor> for Standard {
|
||||||
|
fn sample<R: rand::prelude::Rng + ?Sized>(&self, rng: &mut R) -> VoxelColor {
|
||||||
|
VoxelColor {
|
||||||
|
r: rng.gen(),
|
||||||
|
g: rng.gen(),
|
||||||
|
b: rng.gen(),
|
||||||
|
a: rng.gen(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/client/render/voxel/ray/voxel/grid.rs
Normal file
24
src/client/render/voxel/ray/voxel/grid.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
use nalgebra::Matrix4x3;
|
||||||
|
|
||||||
|
// this has cost me more than a couple of hours trying to figure out alignment :skull:
|
||||||
|
// putting transform at the beginning so I don't have to deal with its alignment
|
||||||
|
// I should probably look into encase (crate)
|
||||||
|
#[repr(C, align(16))]
|
||||||
|
#[derive(Clone, Copy, PartialEq, bytemuck::Zeroable)]
|
||||||
|
pub struct GridInfo {
|
||||||
|
pub transform: Matrix4x3<f32>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl bytemuck::Pod for GridInfo {}
|
||||||
|
|
||||||
|
impl Default for GridInfo {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
transform: Matrix4x3::identity(),
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/client/render/voxel/ray/voxel/group.rs
Normal file
12
src/client/render/voxel/ray/voxel/group.rs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
use nalgebra::{Projective3, Vector3};
|
||||||
|
|
||||||
|
#[repr(C, align(16))]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Zeroable)]
|
||||||
|
pub struct VoxelGroup {
|
||||||
|
pub transform: Projective3<f32>,
|
||||||
|
pub transform_inv: Projective3<f32>,
|
||||||
|
pub scale: u32,
|
||||||
|
pub offset: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl bytemuck::Pod for VoxelGroup {}
|
||||||
198
src/client/render/voxel/ray/voxel/layout.rs
Normal file
198
src/client/render/voxel/ray/voxel/layout.rs
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
use wgpu::TextureFormat;
|
||||||
|
|
||||||
|
use super::{group::VoxelGroup, light::GlobalLight, view::View};
|
||||||
|
use crate::{
|
||||||
|
client::render::util::{Storage, StorageTexture, Uniform},
|
||||||
|
util::oct_tree::OctNode,
|
||||||
|
};
|
||||||
|
use nalgebra::Vector3;
|
||||||
|
|
||||||
|
pub struct Layout {
|
||||||
|
pub texture: StorageTexture,
|
||||||
|
pub view: Uniform<View>,
|
||||||
|
pub voxel_groups: Storage<VoxelGroup>,
|
||||||
|
pub voxels: Storage<OctNode>,
|
||||||
|
pub global_lights: Storage<GlobalLight>,
|
||||||
|
render_bind_layout: wgpu::BindGroupLayout,
|
||||||
|
compute_bind_layout: wgpu::BindGroupLayout,
|
||||||
|
render_pipeline_layout: wgpu::PipelineLayout,
|
||||||
|
compute_pipeline_layout: wgpu::PipelineLayout,
|
||||||
|
format: TextureFormat,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Layout {
|
||||||
|
pub fn init(device: &wgpu::Device, config: &wgpu::SurfaceConfiguration) -> Self {
|
||||||
|
let view = Uniform::init(device, "view", 0);
|
||||||
|
let voxels = Storage::init(device, wgpu::ShaderStages::COMPUTE, "voxels", 1);
|
||||||
|
let voxel_groups = Storage::init(device, wgpu::ShaderStages::COMPUTE, "voxel groups", 2);
|
||||||
|
let global_lights = Storage::init_with(
|
||||||
|
device,
|
||||||
|
wgpu::ShaderStages::COMPUTE,
|
||||||
|
"global lights",
|
||||||
|
3,
|
||||||
|
&[GlobalLight {
|
||||||
|
direction: Vector3::new(-1.0, -2.3, 2.0).normalize(),
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
let texture = StorageTexture::init(
|
||||||
|
device,
|
||||||
|
wgpu::Extent3d {
|
||||||
|
width: config.width,
|
||||||
|
height: config.height,
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
},
|
||||||
|
"compute output",
|
||||||
|
wgpu::ShaderStages::COMPUTE | wgpu::ShaderStages::FRAGMENT,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
let render_bind_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT | wgpu::ShaderStages::VERTEX,
|
||||||
|
ty: wgpu::BindingType::Texture {
|
||||||
|
multisampled: false,
|
||||||
|
view_dimension: wgpu::TextureViewDimension::D2,
|
||||||
|
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 1,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
|
// This should match the filterable field of the
|
||||||
|
// corresponding Texture entry above.
|
||||||
|
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
label: Some("voxel render"),
|
||||||
|
});
|
||||||
|
let compute_bind_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
entries: &[
|
||||||
|
view.bind_group_layout_entry(),
|
||||||
|
voxels.bind_group_layout_entry(),
|
||||||
|
voxel_groups.bind_group_layout_entry(),
|
||||||
|
global_lights.bind_group_layout_entry(),
|
||||||
|
texture.bind_group_layout_entry(),
|
||||||
|
],
|
||||||
|
label: Some("voxel compute"),
|
||||||
|
});
|
||||||
|
let render_pipeline_layout =
|
||||||
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: Some("Tile Pipeline Layout"),
|
||||||
|
bind_group_layouts: &[&render_bind_layout],
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
});
|
||||||
|
let compute_pipeline_layout =
|
||||||
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: Some("voxel compute"),
|
||||||
|
bind_group_layouts: &[&compute_bind_layout],
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
});
|
||||||
|
Self {
|
||||||
|
view,
|
||||||
|
voxels,
|
||||||
|
voxel_groups,
|
||||||
|
global_lights,
|
||||||
|
texture,
|
||||||
|
render_bind_layout,
|
||||||
|
compute_bind_layout,
|
||||||
|
render_pipeline_layout,
|
||||||
|
compute_pipeline_layout,
|
||||||
|
format: config.format,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_bind_group(&self, device: &wgpu::Device) -> wgpu::BindGroup {
|
||||||
|
device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
layout: &self.render_bind_layout,
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&self.texture.view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&self.texture.sampler),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
label: Some("tile_bind_group"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compute_bind_group(&self, device: &wgpu::Device) -> wgpu::BindGroup {
|
||||||
|
device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
layout: &self.compute_bind_layout,
|
||||||
|
entries: &[
|
||||||
|
self.view.bind_group_entry(),
|
||||||
|
self.voxels.bind_group_entry(),
|
||||||
|
self.voxel_groups.bind_group_entry(),
|
||||||
|
self.global_lights.bind_group_entry(),
|
||||||
|
self.texture.bind_group_entry(),
|
||||||
|
],
|
||||||
|
label: Some("voxel compute"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_pipeline(
|
||||||
|
&self,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
shader: wgpu::ShaderModule,
|
||||||
|
) -> wgpu::RenderPipeline {
|
||||||
|
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: Some("Voxel Pipeline"),
|
||||||
|
layout: Some(&self.render_pipeline_layout),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: "vs_main",
|
||||||
|
buffers: &[],
|
||||||
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: "fs_main",
|
||||||
|
targets: &[Some(wgpu::ColorTargetState {
|
||||||
|
format: self.format,
|
||||||
|
blend: Some(wgpu::BlendState::REPLACE),
|
||||||
|
write_mask: wgpu::ColorWrites::ALL,
|
||||||
|
})],
|
||||||
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
|
}),
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::TriangleStrip,
|
||||||
|
strip_index_format: None,
|
||||||
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
|
cull_mode: None,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
|
unclipped_depth: false,
|
||||||
|
conservative: false,
|
||||||
|
},
|
||||||
|
depth_stencil: None,
|
||||||
|
multisample: wgpu::MultisampleState {
|
||||||
|
count: 1,
|
||||||
|
mask: !0,
|
||||||
|
alpha_to_coverage_enabled: true,
|
||||||
|
},
|
||||||
|
multiview: None,
|
||||||
|
cache: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compute_pipeline(
|
||||||
|
&self,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
shader: &wgpu::ShaderModule,
|
||||||
|
) -> wgpu::ComputePipeline {
|
||||||
|
device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
|
||||||
|
label: Some("voxel"),
|
||||||
|
layout: Some(&self.compute_pipeline_layout),
|
||||||
|
module: shader,
|
||||||
|
entry_point: "main",
|
||||||
|
compilation_options: Default::default(),
|
||||||
|
cache: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/client/render/voxel/ray/voxel/light.rs
Normal file
9
src/client/render/voxel/ray/voxel/light.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
use nalgebra::Vector3;
|
||||||
|
|
||||||
|
#[repr(C, align(16))]
|
||||||
|
#[derive(Clone, Copy, PartialEq, bytemuck::Zeroable)]
|
||||||
|
pub struct GlobalLight {
|
||||||
|
pub direction: Vector3<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl bytemuck::Pod for GlobalLight {}
|
||||||
220
src/client/render/voxel/ray/voxel/mod.rs
Normal file
220
src/client/render/voxel/ray/voxel/mod.rs
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
mod color;
|
||||||
|
mod grid;
|
||||||
|
mod group;
|
||||||
|
mod layout;
|
||||||
|
mod light;
|
||||||
|
mod view;
|
||||||
|
|
||||||
|
use super::super::UpdateGridTransform;
|
||||||
|
use crate::{
|
||||||
|
client::{
|
||||||
|
camera::Camera,
|
||||||
|
render::{
|
||||||
|
util::{ArrBufUpdate, StorageTexture},
|
||||||
|
AddChunk, CreateVoxelGrid,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
common::component::chunk,
|
||||||
|
};
|
||||||
|
use bevy_ecs::entity::Entity;
|
||||||
|
pub use color::*;
|
||||||
|
use layout::Layout;
|
||||||
|
use nalgebra::{Projective3, Transform3, Translation3, Vector2, Vector3};
|
||||||
|
use std::{collections::HashMap, ops::Deref};
|
||||||
|
use wgpu::include_wgsl;
|
||||||
|
use {group::VoxelGroup, view::View};
|
||||||
|
|
||||||
|
pub struct VoxelPipeline {
|
||||||
|
layout: Layout,
|
||||||
|
compute_pipeline: wgpu::ComputePipeline,
|
||||||
|
compute_bind_group: wgpu::BindGroup,
|
||||||
|
render_pipeline: wgpu::RenderPipeline,
|
||||||
|
render_bind_group: wgpu::BindGroup,
|
||||||
|
id_map: HashMap<Entity, (usize, VoxelGroup)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
const RENDER_SHADER: wgpu::ShaderModuleDescriptor<'_> = include_wgsl!("shader/render.wgsl");
|
||||||
|
const COMPUTE_SHADER: wgpu::ShaderModuleDescriptor<'_> = include_wgsl!("shader/compute.wgsl");
|
||||||
|
|
||||||
|
impl VoxelPipeline {
|
||||||
|
pub fn new(device: &wgpu::Device, config: &wgpu::SurfaceConfiguration) -> Self {
|
||||||
|
// shaders
|
||||||
|
|
||||||
|
let layout = Layout::init(device, config);
|
||||||
|
|
||||||
|
let render_bind_group = layout.render_bind_group(device);
|
||||||
|
let shader = device.create_shader_module(RENDER_SHADER);
|
||||||
|
let render_pipeline = layout.render_pipeline(device, shader);
|
||||||
|
|
||||||
|
let compute_bind_group = layout.compute_bind_group(device);
|
||||||
|
let shader = device.create_shader_module(COMPUTE_SHADER);
|
||||||
|
let compute_pipeline = layout.compute_pipeline(device, &shader);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
layout,
|
||||||
|
compute_pipeline,
|
||||||
|
compute_bind_group,
|
||||||
|
render_pipeline,
|
||||||
|
render_bind_group,
|
||||||
|
id_map: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset_shader(&mut self, device: &wgpu::Device) {
|
||||||
|
let shader = device.create_shader_module(COMPUTE_SHADER);
|
||||||
|
self.compute_pipeline = self.layout.compute_pipeline(device, &shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_group(
|
||||||
|
&mut self,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
|
belt: &mut wgpu::util::StagingBelt,
|
||||||
|
CreateVoxelGrid {
|
||||||
|
id,
|
||||||
|
pos,
|
||||||
|
orientation,
|
||||||
|
dimensions,
|
||||||
|
grid,
|
||||||
|
}: CreateVoxelGrid,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_shader(&mut self, device: &wgpu::Device) {
|
||||||
|
let Ok(shader) = std::fs::read_to_string(
|
||||||
|
env!("CARGO_MANIFEST_DIR").to_owned() + "/src/client/render/voxel/ray_oct/shader/compute.wgsl",
|
||||||
|
) else {
|
||||||
|
println!("Failed to reload shader!");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
device.push_error_scope(wgpu::ErrorFilter::Validation);
|
||||||
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
|
label: Some("Shader"),
|
||||||
|
source: wgpu::ShaderSource::Wgsl(shader.into()),
|
||||||
|
});
|
||||||
|
if pollster::block_on(device.pop_error_scope()).is_some() {
|
||||||
|
let comp_info = pollster::block_on(shader.get_compilation_info());
|
||||||
|
println!("Failed to compile shaders:");
|
||||||
|
for msg in comp_info.messages {
|
||||||
|
println!("{}", msg.message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.compute_pipeline = self.layout.compute_pipeline(device, &shader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_chunk(
|
||||||
|
&mut self,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
|
belt: &mut wgpu::util::StagingBelt,
|
||||||
|
AddChunk { id, pos, tree, .. }: AddChunk,
|
||||||
|
) {
|
||||||
|
let offset = self.layout.voxels.len();
|
||||||
|
|
||||||
|
let data = tree.raw();
|
||||||
|
let updates = [ArrBufUpdate { offset, data }];
|
||||||
|
let size = offset + data.len();
|
||||||
|
self.layout
|
||||||
|
.voxels
|
||||||
|
.update(device, encoder, belt, size, &updates);
|
||||||
|
|
||||||
|
let proj = Projective3::identity()
|
||||||
|
* Translation3::from((pos.deref() * chunk::SIDE_LENGTH as i32).cast())
|
||||||
|
* Translation3::from(-chunk::DIMENSIONS.cast() / 2.0);
|
||||||
|
let group = VoxelGroup {
|
||||||
|
transform: proj,
|
||||||
|
transform_inv: proj.inverse(),
|
||||||
|
scale: chunk::SCALE,
|
||||||
|
offset: offset as u32,
|
||||||
|
};
|
||||||
|
let updates = [ArrBufUpdate {
|
||||||
|
offset: self.layout.voxel_groups.len(),
|
||||||
|
data: &[group],
|
||||||
|
}];
|
||||||
|
let i = self.layout.voxel_groups.len();
|
||||||
|
let size = i + 1;
|
||||||
|
self.layout
|
||||||
|
.voxel_groups
|
||||||
|
.update(device, encoder, belt, size, &updates);
|
||||||
|
|
||||||
|
self.id_map.insert(id, (i, group));
|
||||||
|
self.compute_bind_group = self.layout.compute_bind_group(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize(&mut self, device: &wgpu::Device, size: Vector2<u32>) {
|
||||||
|
self.layout.texture = StorageTexture::init(
|
||||||
|
device,
|
||||||
|
wgpu::Extent3d {
|
||||||
|
width: size.x,
|
||||||
|
height: size.y,
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
},
|
||||||
|
"idk man im tired",
|
||||||
|
wgpu::ShaderStages::COMPUTE | wgpu::ShaderStages::FRAGMENT,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
self.compute_bind_group = self.layout.compute_bind_group(device);
|
||||||
|
self.render_bind_group = self.layout.render_bind_group(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_transform(
|
||||||
|
&mut self,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
|
belt: &mut wgpu::util::StagingBelt,
|
||||||
|
update: UpdateGridTransform,
|
||||||
|
) {
|
||||||
|
if let Some((i, group)) = self.id_map.get_mut(&update.id) {
|
||||||
|
let offset = Vector3::from_element(-(2u32.pow(group.scale) as f32) / 2.0);
|
||||||
|
let proj = Projective3::identity()
|
||||||
|
* Translation3::from(update.pos)
|
||||||
|
* update.orientation
|
||||||
|
* Translation3::from(offset);
|
||||||
|
group.transform = proj;
|
||||||
|
group.transform_inv = proj.inverse();
|
||||||
|
let updates = [ArrBufUpdate {
|
||||||
|
offset: *i,
|
||||||
|
data: &[*group],
|
||||||
|
}];
|
||||||
|
let size = self.layout.voxel_groups.len();
|
||||||
|
self.layout
|
||||||
|
.voxel_groups
|
||||||
|
.update(device, encoder, belt, size, &updates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_view(
|
||||||
|
&mut self,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
|
belt: &mut wgpu::util::StagingBelt,
|
||||||
|
size: Vector2<u32>,
|
||||||
|
camera: &Camera,
|
||||||
|
) {
|
||||||
|
let transform =
|
||||||
|
Transform3::identity() * Translation3::from(camera.pos) * camera.orientation;
|
||||||
|
let data = View {
|
||||||
|
zoom: camera.scale,
|
||||||
|
transform,
|
||||||
|
};
|
||||||
|
self.layout.view.update(device, encoder, belt, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) {
|
||||||
|
render_pass.set_pipeline(&self.render_pipeline);
|
||||||
|
render_pass.set_bind_group(0, &self.render_bind_group, &[]);
|
||||||
|
render_pass.draw(0..4, 0..1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const WORKGROUP_SIZE: u32 = 8;
|
||||||
|
|
||||||
|
pub fn compute(&self, pass: &mut wgpu::ComputePass) {
|
||||||
|
pass.set_pipeline(&self.compute_pipeline);
|
||||||
|
pass.set_bind_group(0, &self.compute_bind_group, &[]);
|
||||||
|
let buf = &self.layout.texture.buf;
|
||||||
|
let x = (buf.width() - 1) / Self::WORKGROUP_SIZE + 1;
|
||||||
|
let y = (buf.height() - 1) / Self::WORKGROUP_SIZE + 1;
|
||||||
|
pass.dispatch_workgroups(x, y, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
282
src/client/render/voxel/ray/voxel/shader/compute.wgsl
Normal file
282
src/client/render/voxel/ray/voxel/shader/compute.wgsl
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
@group(0) @binding(0)
|
||||||
|
var<uniform> view: View;
|
||||||
|
@group(0) @binding(1)
|
||||||
|
var<storage, read> voxels: array<u32>;
|
||||||
|
@group(0) @binding(2)
|
||||||
|
var<storage, read> voxel_groups: array<VoxelGroup>;
|
||||||
|
@group(0) @binding(3)
|
||||||
|
var<storage, read> global_lights: array<GlobalLight>;
|
||||||
|
@group(0) @binding(4)
|
||||||
|
var output: texture_storage_2d<rgba8unorm, write>;
|
||||||
|
|
||||||
|
struct GlobalLight {
|
||||||
|
dir: vec3<f32>,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct View {
|
||||||
|
transform: mat4x4<f32>,
|
||||||
|
zoom: f32,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VoxelGroup {
|
||||||
|
transform: mat4x4<f32>,
|
||||||
|
transform_inv: mat4x4<f32>,
|
||||||
|
scale: u32,
|
||||||
|
offset: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
@compute
|
||||||
|
@workgroup_size(8, 8, 1)
|
||||||
|
fn main(@builtin(global_invocation_id) cell: vec3<u32>) {
|
||||||
|
let view_dim = textureDimensions(output);
|
||||||
|
// get position of the pixel; eye at origin, pixel on plane z = 1
|
||||||
|
if cell.x >= view_dim.x || cell.y >= view_dim.y {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let view_dim_f = vec2<f32>(view_dim);
|
||||||
|
let aspect = view_dim_f.y / view_dim_f.x;
|
||||||
|
let pixel_pos = vec2<f32>(
|
||||||
|
(vec2<f32>(cell.xy) / view_dim_f - vec2<f32>(0.5)) * vec2<f32>(2.0, -2.0 * aspect)
|
||||||
|
);
|
||||||
|
let pos = view.transform * vec4<f32>(pixel_pos, 1.0, 1.0);
|
||||||
|
let dir = view.transform * vec4<f32>(normalize(vec3<f32>(pixel_pos, view.zoom)), 0.0);
|
||||||
|
|
||||||
|
var color = trace_full(pos, dir);
|
||||||
|
let light_mult = clamp((-dot(dir.xyz, global_lights[0].dir) - 0.99) * 200.0, 0.0, 1.0);
|
||||||
|
let sun_color = light_mult * vec3<f32>(1.0, 1.0, 1.0);
|
||||||
|
let sky_bg = vec3<f32>(0.3, 0.6, 1.0);
|
||||||
|
let sky_color = sun_color + sky_bg * (1.0 - light_mult);
|
||||||
|
color += vec4<f32>(sky_color * (1.0 - color.a), 1.0 - color.a);
|
||||||
|
color.a = 1.0;
|
||||||
|
textureStore(output, cell.xy, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
const LEAF_BIT = 1u << 31u;
|
||||||
|
const LEAF_MASK = ~LEAF_BIT;
|
||||||
|
|
||||||
|
const ZERO3F = vec3<f32>(0.0);
|
||||||
|
const ZERO2F = vec2<f32>(0.0);
|
||||||
|
const FULL_ALPHA = 0.999;
|
||||||
|
const EPSILON = 0.00000000001;
|
||||||
|
const MAX_ITERS = 10000;
|
||||||
|
// NOTE: CANNOT GO HIGHER THAN 23 due to how floating point
|
||||||
|
// numbers are stored and the bit manipulation used
|
||||||
|
const MAX_SCALE: u32 = 16;
|
||||||
|
const AMBIENT: f32 = 0.2;
|
||||||
|
const SPECULAR: f32 = 0.5;
|
||||||
|
|
||||||
|
fn trace_full(pos_view: vec4<f32>, dir_view: vec4<f32>) -> vec4<f32> {
|
||||||
|
let gi = 0;
|
||||||
|
let group = voxel_groups[gi];
|
||||||
|
if group.scale == 0 {
|
||||||
|
return vec4<f32>(0.0);
|
||||||
|
}
|
||||||
|
let dimensions = vec3<u32>(1u << group.scale);
|
||||||
|
let dim_f = vec3<f32>(dimensions);
|
||||||
|
let dim_i = vec3<i32>(dimensions);
|
||||||
|
|
||||||
|
// transform so that group is at 0,0
|
||||||
|
let pos_start = (group.transform_inv * pos_view).xyz;
|
||||||
|
var dir = (group.transform_inv * dir_view).xyz;
|
||||||
|
if dir.x == 0 {dir.x = EPSILON;}
|
||||||
|
if dir.y == 0 {dir.y = EPSILON;}
|
||||||
|
if dir.z == 0 {dir.z = EPSILON;}
|
||||||
|
|
||||||
|
let dir_if = sign(dir);
|
||||||
|
let dir_uf = max(dir_if, vec3<f32>(0.0));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// calculate normals
|
||||||
|
var normals = mat3x3<f32>(
|
||||||
|
(group.transform * vec4<f32>(dir_if.x, 0.0, 0.0, 0.0)).xyz,
|
||||||
|
(group.transform * vec4<f32>(0.0, dir_if.y, 0.0, 0.0)).xyz,
|
||||||
|
(group.transform * vec4<f32>(0.0, 0.0, dir_if.z, 0.0)).xyz,
|
||||||
|
);
|
||||||
|
var axis = 0u;
|
||||||
|
|
||||||
|
// find where ray intersects with group
|
||||||
|
let pos_min = (vec3<f32>(1.0) - dir_uf) * dim_f;
|
||||||
|
// time of intersection; x = td + p, solve for t
|
||||||
|
var t_min = (pos_min - pos_start) / dir;
|
||||||
|
if outside3f(pos_start, ZERO3F, dim_f) {
|
||||||
|
// points of intersection
|
||||||
|
let px = pos_start + t_min.x * dir;
|
||||||
|
let py = pos_start + t_min.y * dir;
|
||||||
|
let pz = pos_start + t_min.z * dir;
|
||||||
|
|
||||||
|
// check if point is in bounds
|
||||||
|
let hit = vec3<bool>(
|
||||||
|
inside2f(px.yz, ZERO2F, dim_f.yz),
|
||||||
|
inside2f(py.xz, ZERO2F, dim_f.xz),
|
||||||
|
inside2f(pz.xy, ZERO2F, dim_f.xy),
|
||||||
|
) && (t_min > ZERO3F);
|
||||||
|
if !any(hit) {
|
||||||
|
return vec4<f32>(0.0);
|
||||||
|
}
|
||||||
|
axis = select(select(2u, 1u, hit.y), 0u, hit.x);
|
||||||
|
}
|
||||||
|
let t_mult = f32(1u << (MAX_SCALE - group.scale));
|
||||||
|
t_min *= t_mult;
|
||||||
|
// time to move 1 unit in each direction
|
||||||
|
let full = f32(1u << MAX_SCALE);
|
||||||
|
let inc_t = abs(1.0 / dir) * full;
|
||||||
|
let t_offset = max(max(t_min.x, t_min.y), t_min.z);
|
||||||
|
var t = max(0.0, t_offset);
|
||||||
|
|
||||||
|
let dir_i = vec3<i32>(dir_if);
|
||||||
|
let dir_u = vec3<u32>(dir_uf);
|
||||||
|
let dir_bits = vec_to_dir(dir_u);
|
||||||
|
let inv_dir_bits = 7 - dir_bits;
|
||||||
|
|
||||||
|
var node_start = 1u;
|
||||||
|
var scale = MAX_SCALE - 1;
|
||||||
|
var scale_exp2 = 0.5;
|
||||||
|
var color = vec4<f32>(0.0);
|
||||||
|
var parents = array<u32, MAX_SCALE>();
|
||||||
|
var prev = LEAF_BIT;
|
||||||
|
var old_t = t / t_mult;
|
||||||
|
|
||||||
|
var child = 0u;
|
||||||
|
var vox_pos = vec3<f32>(1.0);
|
||||||
|
let t_center = t_min + scale_exp2 * inc_t;
|
||||||
|
if t > t_center.x { vox_pos.x = 1.5; child |= 4u; }
|
||||||
|
if t > t_center.y { vox_pos.y = 1.5; child |= 2u; }
|
||||||
|
if t > t_center.z { vox_pos.z = 1.5; child |= 1u; }
|
||||||
|
let min_adj = t_min - inc_t;
|
||||||
|
|
||||||
|
var iters = 0;
|
||||||
|
loop {
|
||||||
|
if iters == MAX_ITERS {
|
||||||
|
return vec4<f32>(1.0, 0.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
iters += 1;
|
||||||
|
let t_corner = vox_pos * inc_t + min_adj;
|
||||||
|
let node = voxels[group.offset + node_start + (child ^ inv_dir_bits)];
|
||||||
|
if node >= LEAF_BIT {
|
||||||
|
if node != prev {
|
||||||
|
if node != LEAF_BIT {
|
||||||
|
let real_t = t / t_mult;
|
||||||
|
let dist = real_t - old_t;
|
||||||
|
old_t = real_t;
|
||||||
|
let filt = min(dist / 64.0, 1.0);
|
||||||
|
if prev == LEAF_BIT + 3 {
|
||||||
|
color.a += filt * (1.0 - color.a);
|
||||||
|
if color.a > FULL_ALPHA { break; }
|
||||||
|
}
|
||||||
|
var pos = (pos_view + dir_view * real_t).xyz;
|
||||||
|
pos[axis] = round(pos[axis]) - (1.0 - dir_uf[axis]);
|
||||||
|
let vcolor = get_color(node & LEAF_MASK, pos);
|
||||||
|
var normal = normals[axis];
|
||||||
|
let light_color = vec3<f32>(1.0);
|
||||||
|
let light_dir = global_lights[0].dir;
|
||||||
|
|
||||||
|
let diffuse = max(dot(light_dir, normal), 0.0) * light_color;
|
||||||
|
let ambient = AMBIENT * light_color;
|
||||||
|
let spec_val = pow(max(dot(dir_view.xyz, reflect(-light_dir, normal)), 0.0), 32.0) * SPECULAR;
|
||||||
|
let specular = spec_val * light_color;
|
||||||
|
let new_color = (ambient + diffuse + specular) * vcolor.xyz;
|
||||||
|
let new_a = min(vcolor.a + spec_val, 1.0);
|
||||||
|
|
||||||
|
color += vec4<f32>(new_color.xyz * new_a, new_a) * (1.0 - color.a);
|
||||||
|
if color.a > FULL_ALPHA { break; }
|
||||||
|
}
|
||||||
|
prev = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to next time point and determine which axis to move along
|
||||||
|
let t_next = t_corner + scale_exp2 * inc_t;
|
||||||
|
t = min(min(t_next.x, t_next.y), t_next.z);
|
||||||
|
axis = select(select(0u, 1u, t == t_next.y), 2u, t == t_next.z);
|
||||||
|
let move_dir = 4u >> axis;
|
||||||
|
|
||||||
|
// check if need to pop stack
|
||||||
|
if (child & move_dir) > 0 {
|
||||||
|
// calculate new scale; first differing bit after adding
|
||||||
|
let axis_pos = vox_pos[axis];
|
||||||
|
// AWARE
|
||||||
|
let differing = bitcast<u32>(axis_pos) ^ bitcast<u32>(axis_pos + scale_exp2);
|
||||||
|
scale = (bitcast<u32>(f32(differing)) >> 23) - 127 - (23 - MAX_SCALE);
|
||||||
|
scale_exp2 = bitcast<f32>((scale + 127 - MAX_SCALE) << 23);
|
||||||
|
if scale >= MAX_SCALE { break; }
|
||||||
|
|
||||||
|
// restore & recalculate parent
|
||||||
|
let parent_info = parents[scale];
|
||||||
|
node_start = parent_info >> 3;
|
||||||
|
child = parent_info & 7;
|
||||||
|
let scale_vec = vec3<u32>(scale + 23 - MAX_SCALE);
|
||||||
|
// remove bits lower than current scale
|
||||||
|
vox_pos = bitcast<vec3<f32>>((bitcast<vec3<u32>>(vox_pos) >> scale_vec) << scale_vec);
|
||||||
|
}
|
||||||
|
// move to next child and voxel position
|
||||||
|
child += move_dir;
|
||||||
|
vox_pos[axis] += scale_exp2;
|
||||||
|
} else {
|
||||||
|
// push current node to stack
|
||||||
|
parents[scale] = (node_start << 3) + child;
|
||||||
|
scale -= 1u;
|
||||||
|
|
||||||
|
// calculate child node vars
|
||||||
|
scale_exp2 *= 0.5;
|
||||||
|
child = 0u;
|
||||||
|
let t_center = t_corner + scale_exp2 * inc_t;
|
||||||
|
if t > t_center.x { vox_pos.x += scale_exp2; child |= 4u; }
|
||||||
|
if t > t_center.y { vox_pos.y += scale_exp2; child |= 2u; }
|
||||||
|
if t > t_center.z { vox_pos.z += scale_exp2; child |= 1u; }
|
||||||
|
node_start = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// let fog = min(t / t_mult / 1000.0, 1.0);
|
||||||
|
// return vec4<f32>(color.xyz * (1.0 - fog) + vec3<f32>(fog), color.a * (1.0 - fog) + fog);
|
||||||
|
// return vec4<f32>(f32(iters) / f32(MAX_ITERS), 0.0, 0.0, 1.0);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dir_to_vec(bits: u32) -> vec3<u32> {
|
||||||
|
return vec3<u32>(bits >> 2, (bits & 2) >> 1, bits & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vec_to_dir(vec: vec3<u32>) -> u32 {
|
||||||
|
return vec.x * 4 + vec.y * 2 + vec.z * 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_color(id: u32, pos: vec3<f32>) -> vec4<f32> {
|
||||||
|
let random = random(floor(pos));
|
||||||
|
let random2 = random(floor(pos) + vec3<f32>(0.0001));
|
||||||
|
switch id {
|
||||||
|
case 0u: {
|
||||||
|
return vec4<f32>(0.0);
|
||||||
|
}
|
||||||
|
case 1u: {
|
||||||
|
let color = vec3<f32>(0.5, 0.5, 0.5 + random * 0.2) * (random2 * 0.4 + 0.8);
|
||||||
|
return vec4<f32>(color, 1.0);
|
||||||
|
}
|
||||||
|
case 2u: {
|
||||||
|
let color = vec3<f32>(0.4 + random * 0.2, 0.9, 0.4 + random * 0.2) * (random2 * 0.2 + 0.9);
|
||||||
|
return vec4<f32>(color, 1.0);
|
||||||
|
}
|
||||||
|
case 3u: {
|
||||||
|
let color = vec3<f32>(0.5, 0.5, 1.0) * (random2 * 0.2 + 0.8);
|
||||||
|
return vec4<f32>(color, 0.5);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn random(pos: vec3<f32>) -> f32 {
|
||||||
|
return fract(sin(dot(pos, vec3<f32>(12.9898, 78.233, 25.1279))) * 43758.5453123);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outside3f(v: vec3<f32>, low: vec3<f32>, high: vec3<f32>) -> bool {
|
||||||
|
return any(v < low) || any(v > high);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inside2f(v: vec2<f32>, low: vec2<f32>, high: vec2<f32>) -> bool {
|
||||||
|
return all(v >= low) && all(v <= high);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inside3i(v: vec3<i32>, low: vec3<i32>, high: vec3<i32>) -> bool {
|
||||||
|
return all(v >= low) && all(v <= high);
|
||||||
|
}
|
||||||
419
src/client/render/voxel/ray/voxel/shader/compute_shadow.wgsl
Normal file
419
src/client/render/voxel/ray/voxel/shader/compute_shadow.wgsl
Normal file
@@ -0,0 +1,419 @@
|
|||||||
|
@group(0) @binding(0)
|
||||||
|
var<uniform> view: View;
|
||||||
|
@group(0) @binding(1)
|
||||||
|
var<storage, read> voxels: array<u32>;
|
||||||
|
@group(0) @binding(2)
|
||||||
|
var<storage, read> voxel_groups: array<VoxelGroup>;
|
||||||
|
@group(0) @binding(3)
|
||||||
|
var<storage, read> global_lights: array<GlobalLight>;
|
||||||
|
@group(0) @binding(4)
|
||||||
|
var output: texture_storage_2d<rgba8unorm, write>;
|
||||||
|
|
||||||
|
struct GlobalLight {
|
||||||
|
dir: vec3<f32>,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct View {
|
||||||
|
transform: mat4x4<f32>,
|
||||||
|
zoom: f32,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VoxelGroup {
|
||||||
|
transform: mat4x4<f32>,
|
||||||
|
transform_inv: mat4x4<f32>,
|
||||||
|
scale: u32,
|
||||||
|
offset: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
@compute
|
||||||
|
@workgroup_size(8, 8, 1)
|
||||||
|
fn main(@builtin(global_invocation_id) cell: vec3<u32>) {
|
||||||
|
let view_dim = textureDimensions(output);
|
||||||
|
// get position of the pixel; eye at origin, pixel on plane z = 1
|
||||||
|
if cell.x >= view_dim.x || cell.y >= view_dim.y {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let view_dim_f = vec2<f32>(view_dim);
|
||||||
|
let aspect = view_dim_f.y / view_dim_f.x;
|
||||||
|
let pixel_pos = vec3<f32>(
|
||||||
|
(vec2<f32>(cell.xy) / view_dim_f - vec2<f32>(0.5)) * vec2<f32>(2.0, -2.0 * aspect),
|
||||||
|
view.zoom
|
||||||
|
);
|
||||||
|
let pos = view.transform * vec4<f32>(pixel_pos, 1.0);
|
||||||
|
let dir = view.transform * vec4<f32>(normalize(pixel_pos), 0.0);
|
||||||
|
|
||||||
|
var color = trace_full(pos, dir);
|
||||||
|
let light_mult = clamp((-dot(dir.xyz, global_lights[0].dir) - 0.99) * 200.0, 0.0, 1.0);
|
||||||
|
let sun_color = light_mult * vec3<f32>(1.0, 1.0, 1.0);
|
||||||
|
let sky_bg = vec3<f32>(0.3, 0.6, 1.0);
|
||||||
|
let sky_color = sun_color + sky_bg * (1.0 - light_mult);
|
||||||
|
color += vec4<f32>(sky_color * (1.0 - color.a), 1.0 - color.a);
|
||||||
|
color.a = 1.0;
|
||||||
|
textureStore(output, cell.xy, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
const LEAF_BIT = 1u << 31u;
|
||||||
|
const LEAF_MASK = ~LEAF_BIT;
|
||||||
|
|
||||||
|
const ZERO3F = vec3<f32>(0.0);
|
||||||
|
const ZERO2F = vec2<f32>(0.0);
|
||||||
|
const FULL_ALPHA = 0.999;
|
||||||
|
const EPSILON = 0.00000000001;
|
||||||
|
const MAX_ITERS = 2000;
|
||||||
|
// NOTE: CANNOT GO HIGHER THAN 23 due to how floating point
|
||||||
|
// numbers are stored and the bit manipulation used
|
||||||
|
const MAX_SCALE: u32 = 10;
|
||||||
|
|
||||||
|
fn trace_full(pos_view: vec4<f32>, dir_view: vec4<f32>) -> vec4<f32> {
|
||||||
|
let gi = 0;
|
||||||
|
let group = voxel_groups[gi];
|
||||||
|
if group.scale == 0 {
|
||||||
|
return vec4<f32>(0.0);
|
||||||
|
}
|
||||||
|
let dimensions = vec3<u32>(1u << group.scale);
|
||||||
|
let dim_f = vec3<f32>(dimensions);
|
||||||
|
let dim_i = vec3<i32>(dimensions);
|
||||||
|
|
||||||
|
// transform so that group is at 0,0
|
||||||
|
let pos_start = (group.transform_inv * pos_view).xyz;
|
||||||
|
var dir = (group.transform_inv * dir_view).xyz;
|
||||||
|
if dir.x == 0 {dir.x = EPSILON;}
|
||||||
|
if dir.y == 0 {dir.y = EPSILON;}
|
||||||
|
if dir.z == 0 {dir.z = EPSILON;}
|
||||||
|
|
||||||
|
let dir_if = sign(dir);
|
||||||
|
let dir_uf = max(dir_if, vec3<f32>(0.0));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// calculate normals
|
||||||
|
var normals = mat3x3<f32>(
|
||||||
|
(group.transform * vec4<f32>(dir_if.x, 0.0, 0.0, 0.0)).xyz,
|
||||||
|
(group.transform * vec4<f32>(0.0, dir_if.y, 0.0, 0.0)).xyz,
|
||||||
|
(group.transform * vec4<f32>(0.0, 0.0, dir_if.z, 0.0)).xyz,
|
||||||
|
);
|
||||||
|
var axis = 0u;
|
||||||
|
|
||||||
|
// find where ray intersects with group
|
||||||
|
let pos_min = (vec3<f32>(1.0) - dir_uf) * dim_f;
|
||||||
|
// time of intersection; x = td + p, solve for t
|
||||||
|
var t_min = (pos_min - pos_start) / dir;
|
||||||
|
if outside3f(pos_start, ZERO3F, dim_f) {
|
||||||
|
// points of intersection
|
||||||
|
let px = pos_start + t_min.x * dir;
|
||||||
|
let py = pos_start + t_min.y * dir;
|
||||||
|
let pz = pos_start + t_min.z * dir;
|
||||||
|
|
||||||
|
// check if point is in bounds
|
||||||
|
let hit = vec3<bool>(
|
||||||
|
inside2f(px.yz, ZERO2F, dim_f.yz),
|
||||||
|
inside2f(py.xz, ZERO2F, dim_f.xz),
|
||||||
|
inside2f(pz.xy, ZERO2F, dim_f.xy),
|
||||||
|
) && (t_min > ZERO3F);
|
||||||
|
if !any(hit) {
|
||||||
|
return vec4<f32>(0.0);
|
||||||
|
}
|
||||||
|
axis = select(select(2u, 1u, hit.y), 0u, hit.x);
|
||||||
|
}
|
||||||
|
let t_mult = f32(1u << (MAX_SCALE - group.scale));
|
||||||
|
t_min *= t_mult;
|
||||||
|
// time to move 1 unit in each direction
|
||||||
|
let full = f32(1u << MAX_SCALE);
|
||||||
|
let inc_t = abs(1.0 / dir) * full;
|
||||||
|
let t_offset = max(max(t_min.x, t_min.y), t_min.z);
|
||||||
|
var t = max(0.0, t_offset);
|
||||||
|
|
||||||
|
let dir_i = vec3<i32>(dir_if);
|
||||||
|
let dir_u = vec3<u32>((dir_i + vec3<i32>(1)) / 2);
|
||||||
|
let dir_bits = vec_to_dir(dir_u);
|
||||||
|
let inv_dir_bits = 7 - dir_bits;
|
||||||
|
|
||||||
|
var node_start = 1u;
|
||||||
|
var scale = MAX_SCALE - 1;
|
||||||
|
var scale_exp2 = 0.5;
|
||||||
|
var skip = LEAF_BIT;
|
||||||
|
var color = vec4<f32>(0.0);
|
||||||
|
var parents = array<u32, MAX_SCALE>();
|
||||||
|
|
||||||
|
var child = 0u;
|
||||||
|
var vox_pos = vec3<f32>(1.0);
|
||||||
|
let t_center = t_min + scale_exp2 * inc_t;
|
||||||
|
if t > t_center.x { vox_pos.x = 1.5; child |= 4u; }
|
||||||
|
if t > t_center.y { vox_pos.y = 1.5; child |= 2u; }
|
||||||
|
if t > t_center.z { vox_pos.z = 1.5; child |= 1u; }
|
||||||
|
let min_adj = t_min - inc_t;
|
||||||
|
|
||||||
|
var iters = 0;
|
||||||
|
loop {
|
||||||
|
if iters == MAX_ITERS {
|
||||||
|
return vec4<f32>(1.0, 0.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
iters += 1;
|
||||||
|
let t_corner = vox_pos * inc_t + min_adj;
|
||||||
|
let node = voxels[group.offset + node_start + (child ^ inv_dir_bits)];
|
||||||
|
if node >= LEAF_BIT {
|
||||||
|
if node != skip && node != LEAF_BIT {
|
||||||
|
skip = node;
|
||||||
|
let normal = normals[axis];
|
||||||
|
let sun_dir = global_lights[0].dir;
|
||||||
|
let new_pos = pos_view + dir_view * t / t_mult - vec4<f32>(normals[axis] * 0.001, 0.0);
|
||||||
|
|
||||||
|
let light = trace_light(new_pos, vec4<f32>(-sun_dir, 0.0));
|
||||||
|
let diffuse = max(dot(sun_dir, normal) + 0.1, 0.0);
|
||||||
|
let ambient = 0.2;
|
||||||
|
let specular = (exp(max(
|
||||||
|
-(dot(reflect(dir_view.xyz, normal), sun_dir) + 0.90) * 4.0, 0.0
|
||||||
|
)) - 1.0) * light;
|
||||||
|
let lighting = max(diffuse * light.a, ambient);
|
||||||
|
|
||||||
|
let vcolor = get_color(node & LEAF_MASK);
|
||||||
|
let new_rgb = min(vcolor.xyz * lighting + specular.xyz + light.xyz * vcolor.xyz, vec3<f32>(1.0));
|
||||||
|
let new_a = min(vcolor.a + specular.a, 1.0);
|
||||||
|
let new_color = vec4<f32>(new_rgb, new_a);
|
||||||
|
color += vec4<f32>(new_color.xyz * new_color.a, new_color.a) * (1.0 - color.a);
|
||||||
|
if color.a > FULL_ALPHA { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to next time point and determine which axis to move along
|
||||||
|
let t_next = t_corner + scale_exp2 * inc_t;
|
||||||
|
t = min(min(t_next.x, t_next.y), t_next.z);
|
||||||
|
axis = select(select(0u, 1u, t == t_next.y), 2u, t == t_next.z);
|
||||||
|
let move_dir = 4u >> axis;
|
||||||
|
|
||||||
|
// check if need to pop stack
|
||||||
|
if (child & move_dir) > 0 {
|
||||||
|
// calculate new scale; first differing bit after adding
|
||||||
|
let axis_pos = vox_pos[axis];
|
||||||
|
// AWARE
|
||||||
|
let differing = bitcast<u32>(axis_pos) ^ bitcast<u32>(axis_pos + scale_exp2);
|
||||||
|
scale = (bitcast<u32>(f32(differing)) >> 23) - 127 - (23 - MAX_SCALE);
|
||||||
|
scale_exp2 = bitcast<f32>((scale + 127 - MAX_SCALE) << 23);
|
||||||
|
if scale >= MAX_SCALE { break; }
|
||||||
|
|
||||||
|
// restore & recalculate parent
|
||||||
|
let parent_info = parents[scale];
|
||||||
|
node_start = parent_info >> 3;
|
||||||
|
child = parent_info & 7;
|
||||||
|
let scale_vec = vec3<u32>(scale + 23 - MAX_SCALE);
|
||||||
|
// remove bits lower than current scale
|
||||||
|
vox_pos = bitcast<vec3<f32>>((bitcast<vec3<u32>>(vox_pos) >> scale_vec) << scale_vec);
|
||||||
|
}
|
||||||
|
// move to next child and voxel position
|
||||||
|
child += move_dir;
|
||||||
|
vox_pos[axis] += scale_exp2;
|
||||||
|
} else {
|
||||||
|
// push current node to stack
|
||||||
|
parents[scale] = (node_start << 3) + child;
|
||||||
|
scale -= 1u;
|
||||||
|
|
||||||
|
// calculate child node vars
|
||||||
|
scale_exp2 *= 0.5;
|
||||||
|
child = 0u;
|
||||||
|
let t_center = t_corner + scale_exp2 * inc_t;
|
||||||
|
if t > t_center.x { vox_pos.x += scale_exp2; child |= 4u; }
|
||||||
|
if t > t_center.y { vox_pos.y += scale_exp2; child |= 2u; }
|
||||||
|
if t > t_center.z { vox_pos.z += scale_exp2; child |= 1u; }
|
||||||
|
node_start += 8 + node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// return vec4<f32>(f32(iters) / f32(MAX_ITERS), 0.0, 0.0, 1.0);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trace_light(pos_view: vec4<f32>, dir_view: vec4<f32>) -> vec4<f32> {
|
||||||
|
let gi = 0;
|
||||||
|
let group = voxel_groups[gi];
|
||||||
|
if group.scale == 0 {
|
||||||
|
return vec4<f32>(0.0);
|
||||||
|
}
|
||||||
|
let dimensions = vec3<u32>(1u << group.scale);
|
||||||
|
let dim_f = vec3<f32>(dimensions);
|
||||||
|
let dim_i = vec3<i32>(dimensions);
|
||||||
|
|
||||||
|
// transform so that group is at 0,0
|
||||||
|
let pos_start = (group.transform_inv * pos_view).xyz;
|
||||||
|
var dir = (group.transform_inv * dir_view).xyz;
|
||||||
|
if dir.x == 0 {dir.x = EPSILON;}
|
||||||
|
if dir.y == 0 {dir.y = EPSILON;}
|
||||||
|
if dir.z == 0 {dir.z = EPSILON;}
|
||||||
|
|
||||||
|
let dir_if = sign(dir);
|
||||||
|
let dir_uf = max(dir_if, vec3<f32>(0.0));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// calculate normals
|
||||||
|
var normals = mat3x3<f32>(
|
||||||
|
(group.transform * vec4<f32>(dir_if.x, 0.0, 0.0, 0.0)).xyz,
|
||||||
|
(group.transform * vec4<f32>(0.0, dir_if.y, 0.0, 0.0)).xyz,
|
||||||
|
(group.transform * vec4<f32>(0.0, 0.0, dir_if.z, 0.0)).xyz,
|
||||||
|
);
|
||||||
|
var axis = 0u;
|
||||||
|
|
||||||
|
// find where ray intersects with group
|
||||||
|
let pos_min = (vec3<f32>(1.0) - dir_uf) * dim_f;
|
||||||
|
// time of intersection; x = td + p, solve for t
|
||||||
|
var t_min = (pos_min - pos_start) / dir;
|
||||||
|
if outside3f(pos_start, ZERO3F, dim_f) {
|
||||||
|
// points of intersection
|
||||||
|
let px = pos_start + t_min.x * dir;
|
||||||
|
let py = pos_start + t_min.y * dir;
|
||||||
|
let pz = pos_start + t_min.z * dir;
|
||||||
|
|
||||||
|
// check if point is in bounds
|
||||||
|
let hit = vec3<bool>(
|
||||||
|
inside2f(px.yz, ZERO2F, dim_f.yz),
|
||||||
|
inside2f(py.xz, ZERO2F, dim_f.xz),
|
||||||
|
inside2f(pz.xy, ZERO2F, dim_f.xy),
|
||||||
|
) && (t_min > ZERO3F);
|
||||||
|
if !any(hit) {
|
||||||
|
return vec4<f32>(0.0);
|
||||||
|
}
|
||||||
|
axis = select(select(2u, 1u, hit.y), 0u, hit.x);
|
||||||
|
}
|
||||||
|
let t_mult = f32(1u << (MAX_SCALE - group.scale));
|
||||||
|
t_min *= t_mult;
|
||||||
|
// time to move 1 unit in each direction
|
||||||
|
let full = f32(1u << MAX_SCALE);
|
||||||
|
let inc_t = abs(1.0 / dir) * full;
|
||||||
|
let t_offset = max(max(t_min.x, t_min.y), t_min.z);
|
||||||
|
var t = max(0.0, t_offset);
|
||||||
|
var old_t = t;
|
||||||
|
|
||||||
|
let dir_i = vec3<i32>(dir_if);
|
||||||
|
let dir_u = vec3<u32>((dir_i + vec3<i32>(1)) / 2);
|
||||||
|
let dir_bits = vec_to_dir(dir_u);
|
||||||
|
let inv_dir_bits = 7 - dir_bits;
|
||||||
|
|
||||||
|
var node_start = 1u;
|
||||||
|
var scale = MAX_SCALE - 1;
|
||||||
|
var scale_exp2 = 0.5;
|
||||||
|
var mask = vec4<f32>(0.0);
|
||||||
|
var skip = LEAF_BIT;
|
||||||
|
var parents = array<u32, MAX_SCALE>();
|
||||||
|
|
||||||
|
var child = 0u;
|
||||||
|
var vox_pos = vec3<f32>(1.0);
|
||||||
|
let t_center = t_min + scale_exp2 * inc_t;
|
||||||
|
if t > t_center.x { vox_pos.x = 1.5; child |= 4u; }
|
||||||
|
if t > t_center.y { vox_pos.y = 1.5; child |= 2u; }
|
||||||
|
if t > t_center.z { vox_pos.z = 1.5; child |= 1u; }
|
||||||
|
let min_adj = t_min - inc_t;
|
||||||
|
var data = 0u;
|
||||||
|
|
||||||
|
var iters = 0;
|
||||||
|
loop {
|
||||||
|
if iters == MAX_ITERS {
|
||||||
|
return vec4<f32>(1.0, 0.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
iters += 1;
|
||||||
|
let t_corner = vox_pos * inc_t + min_adj;
|
||||||
|
let node = voxels[group.offset + node_start + (child ^ inv_dir_bits)];
|
||||||
|
if node >= LEAF_BIT {
|
||||||
|
if node != skip && node != LEAF_BIT {
|
||||||
|
skip = node;
|
||||||
|
if data == 3 {
|
||||||
|
let dist = (t - old_t) / t_mult;
|
||||||
|
let vcolor = vec4<f32>(vec3<f32>(0.0), min(dist / 12.0, 1.0));
|
||||||
|
mask += vec4<f32>(vcolor.xyz * vcolor.a, vcolor.a) * (1.0 - mask.a);
|
||||||
|
}
|
||||||
|
data = node & LEAF_MASK;
|
||||||
|
if data != 3 && data != 0 {
|
||||||
|
let vcolor = get_color(data);
|
||||||
|
mask += vec4<f32>(vcolor.xyz * vcolor.a, vcolor.a) * (1.0 - mask.a);
|
||||||
|
}
|
||||||
|
old_t = t;
|
||||||
|
if mask.a > FULL_ALPHA { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to next time point and determine which axis to move along
|
||||||
|
let t_next = t_corner + scale_exp2 * inc_t;
|
||||||
|
t = min(min(t_next.x, t_next.y), t_next.z);
|
||||||
|
axis = select(select(0u, 1u, t == t_next.y), 2u, t == t_next.z);
|
||||||
|
let move_dir = 4u >> axis;
|
||||||
|
|
||||||
|
// check if need to pop stack
|
||||||
|
if (child & move_dir) > 0 {
|
||||||
|
// calculate new scale; first differing bit after adding
|
||||||
|
let axis_pos = vox_pos[axis];
|
||||||
|
// AWARE
|
||||||
|
let differing = bitcast<u32>(axis_pos) ^ bitcast<u32>(axis_pos + scale_exp2);
|
||||||
|
scale = (bitcast<u32>(f32(differing)) >> 23) - 127 - (23 - MAX_SCALE);
|
||||||
|
scale_exp2 = bitcast<f32>((scale + 127 - MAX_SCALE) << 23);
|
||||||
|
if scale >= MAX_SCALE { break; }
|
||||||
|
|
||||||
|
// restore & recalculate parent
|
||||||
|
let parent_info = parents[scale];
|
||||||
|
node_start = parent_info >> 3;
|
||||||
|
child = parent_info & 7;
|
||||||
|
let scale_vec = vec3<u32>(scale + 23 - MAX_SCALE);
|
||||||
|
// remove bits lower than current scale
|
||||||
|
vox_pos = bitcast<vec3<f32>>((bitcast<vec3<u32>>(vox_pos) >> scale_vec) << scale_vec);
|
||||||
|
}
|
||||||
|
// move to next child and voxel position
|
||||||
|
child += move_dir;
|
||||||
|
vox_pos[axis] += scale_exp2;
|
||||||
|
} else {
|
||||||
|
// push current node to stack
|
||||||
|
parents[scale] = (node_start << 3) + child;
|
||||||
|
scale -= 1u;
|
||||||
|
|
||||||
|
// calculate child node vars
|
||||||
|
scale_exp2 *= 0.5;
|
||||||
|
child = 0u;
|
||||||
|
let t_center = t_corner + scale_exp2 * inc_t;
|
||||||
|
if t > t_center.x { vox_pos.x += scale_exp2; child |= 4u; }
|
||||||
|
if t > t_center.y { vox_pos.y += scale_exp2; child |= 2u; }
|
||||||
|
if t > t_center.z { vox_pos.z += scale_exp2; child |= 1u; }
|
||||||
|
node_start += 8 + node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if data == 3 {
|
||||||
|
let dist = (t - old_t) / t_mult;
|
||||||
|
let vcolor = vec4<f32>(vec3<f32>(0.0), min(dist / 12.0, 1.0));
|
||||||
|
mask += vec4<f32>(vcolor.xyz * vcolor.a, vcolor.a) * (1.0 - mask.a);
|
||||||
|
}
|
||||||
|
mask.a = 1.0 - mask.a;
|
||||||
|
mask = vec4<f32>(mask.a * mask.xyz, mask.a);
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dir_to_vec(bits: u32) -> vec3<u32> {
|
||||||
|
return vec3<u32>(bits >> 2, (bits & 2) >> 1, bits & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vec_to_dir(vec: vec3<u32>) -> u32 {
|
||||||
|
return vec.x * 4 + vec.y * 2 + vec.z * 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_color(id: u32) -> vec4<f32> {
|
||||||
|
switch id {
|
||||||
|
case 0u: {
|
||||||
|
return vec4<f32>(0.0);
|
||||||
|
}
|
||||||
|
case 1u: {
|
||||||
|
return vec4<f32>(0.5, 0.5, 0.5, 1.0);
|
||||||
|
}
|
||||||
|
case 2u: {
|
||||||
|
return vec4<f32>(0.5, 1.0, 0.5, 1.0);
|
||||||
|
}
|
||||||
|
case 3u: {
|
||||||
|
return vec4<f32>(0.5, 0.5, 1.0, 0.5);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outside3f(v: vec3<f32>, low: vec3<f32>, high: vec3<f32>) -> bool {
|
||||||
|
return any(v < low) || any(v > high);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inside2f(v: vec2<f32>, low: vec2<f32>, high: vec2<f32>) -> bool {
|
||||||
|
return all(v >= low) && all(v <= high);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inside3i(v: vec3<i32>, low: vec3<i32>, high: vec3<i32>) -> bool {
|
||||||
|
return all(v >= low) && all(v <= high);
|
||||||
|
}
|
||||||
364
src/client/render/voxel/ray/voxel/shader/compute_struct.wgsl
Normal file
364
src/client/render/voxel/ray/voxel/shader/compute_struct.wgsl
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
@group(0) @binding(0)
|
||||||
|
var<uniform> view: View;
|
||||||
|
@group(0) @binding(1)
|
||||||
|
var<storage, read> voxels: array<u32>;
|
||||||
|
@group(0) @binding(2)
|
||||||
|
var<storage, read> voxel_groups: array<VoxelGroup>;
|
||||||
|
@group(0) @binding(3)
|
||||||
|
var<storage, read> global_lights: array<GlobalLight>;
|
||||||
|
@group(0) @binding(4)
|
||||||
|
var output: texture_storage_2d<rgba8unorm, write>;
|
||||||
|
|
||||||
|
struct GlobalLight {
|
||||||
|
dir: vec3<f32>,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct View {
|
||||||
|
transform: mat4x4<f32>,
|
||||||
|
zoom: f32,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VoxelGroup {
|
||||||
|
transform: mat4x4<f32>,
|
||||||
|
transform_inv: mat4x4<f32>,
|
||||||
|
scale: u32,
|
||||||
|
offset: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
@compute
|
||||||
|
@workgroup_size(8, 8, 1)
|
||||||
|
fn main(@builtin(global_invocation_id) cell: vec3<u32>) {
|
||||||
|
let view_dim = textureDimensions(output);
|
||||||
|
// get position of the pixel; eye at origin, pixel on plane z = 1
|
||||||
|
if cell.x >= view_dim.x || cell.y >= view_dim.y {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let view_dim_f = vec2<f32>(view_dim);
|
||||||
|
let aspect = view_dim_f.y / view_dim_f.x;
|
||||||
|
let pixel_pos = vec3<f32>(
|
||||||
|
(vec2<f32>(cell.xy) / view_dim_f - vec2<f32>(0.5)) * vec2<f32>(2.0, -2.0 * aspect),
|
||||||
|
view.zoom
|
||||||
|
);
|
||||||
|
let pos = view.transform * vec4<f32>(pixel_pos, 1.0);
|
||||||
|
let dir = view.transform * vec4<f32>(normalize(pixel_pos), 0.0);
|
||||||
|
|
||||||
|
let start = start_ray(pos, dir);
|
||||||
|
var color = vec4<f32>(0.0);
|
||||||
|
let ambient = 0.2;
|
||||||
|
|
||||||
|
if start.hit {
|
||||||
|
var res = ray_next(start.ray, LEAF_BIT);
|
||||||
|
var normals = start.normals;
|
||||||
|
let specular = (exp(max(
|
||||||
|
-(dot(reflect(dir.xyz, normals[res.ray.axis]), global_lights[0].dir) + 0.90) * 4.0, 0.0
|
||||||
|
)) - 1.0);
|
||||||
|
while res.data != 0 {
|
||||||
|
let data = res.data & LEAF_MASK;
|
||||||
|
if data != 0 {
|
||||||
|
let vcolor = get_color(data);
|
||||||
|
let diffuse = max(dot(global_lights[0].dir, normals[res.ray.axis]) + 0.1, 0.0);
|
||||||
|
let light = max(diffuse, ambient);
|
||||||
|
let new_color = min(vcolor.xyz * light, vec3<f32>(1.0));
|
||||||
|
color += vec4<f32>(new_color.xyz * vcolor.a, vcolor.a) * (1.0 - color.a);
|
||||||
|
if color.a > FULL_ALPHA { break; }
|
||||||
|
}
|
||||||
|
let old_t = res.ray.t;
|
||||||
|
res = ray_next(res.ray, res.data);
|
||||||
|
if data == 3 {
|
||||||
|
let dist = (res.ray.t - old_t) / start.t_mult;
|
||||||
|
let a = min(dist / 12.0, 1.0);
|
||||||
|
color += vec4<f32>(vec3<f32>(0.0) * a, a) * (1.0 - color.a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if color.a != 0 {
|
||||||
|
let pos = pos + dir * res.ray.t / start.t_mult - vec4<f32>(normals[res.ray.axis] * 0.001, 0.0);
|
||||||
|
let dir = vec4<f32>(-global_lights[0].dir, 0.0);
|
||||||
|
let start = start_ray(pos, dir);
|
||||||
|
res = ray_next(start.ray, LEAF_BIT);
|
||||||
|
var light = 1.0;
|
||||||
|
while res.data != 0 {
|
||||||
|
let data = res.data & LEAF_MASK;
|
||||||
|
if data != 0 {
|
||||||
|
let vcolor = get_color(data);
|
||||||
|
if data != 3 { light -= vcolor.a * light; }
|
||||||
|
if light <= 0 { break; }
|
||||||
|
}
|
||||||
|
let old_t = res.ray.t;
|
||||||
|
res = ray_next(res.ray, res.data);
|
||||||
|
if data == 3 {
|
||||||
|
let dist = (res.ray.t - old_t) / start.t_mult;
|
||||||
|
let a = min(dist / 12.0, 1.0);
|
||||||
|
light -= a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
color = vec4<f32>(color.xyz * max(light, ambient), color.a) + vec4<f32>(vec3<f32>(specular * light), 0.0);
|
||||||
|
}
|
||||||
|
// color = vec4<f32>(pos.xyz / 128.0, 1.0);
|
||||||
|
}
|
||||||
|
// var color = trace_full(pos, dir);
|
||||||
|
let light_mult = clamp((-dot(dir.xyz, global_lights[0].dir) - 0.99) * 200.0, 0.0, 1.0);
|
||||||
|
let sun_color = light_mult * vec3<f32>(1.0, 1.0, 1.0);
|
||||||
|
let sky_bg = vec3<f32>(0.3, 0.6, 1.0);
|
||||||
|
let sky_color = sun_color + sky_bg * (1.0 - light_mult);
|
||||||
|
color += vec4<f32>(sky_color * (1.0 - color.a), 1.0 - color.a);
|
||||||
|
color.a = 1.0;
|
||||||
|
textureStore(output, cell.xy, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
const LEAF_BIT = 1u << 31u;
|
||||||
|
const LEAF_MASK = ~LEAF_BIT;
|
||||||
|
|
||||||
|
const ZERO3F = vec3<f32>(0.0);
|
||||||
|
const ZERO2F = vec2<f32>(0.0);
|
||||||
|
const FULL_ALPHA = 0.999;
|
||||||
|
const EPSILON = 0.00000000001;
|
||||||
|
const MAX_ITERS = 2000;
|
||||||
|
// NOTE: CANNOT GO HIGHER THAN 23 due to how floating point
|
||||||
|
// numbers are stored and the bit manipulation used
|
||||||
|
const MAX_SCALE: u32 = 10;
|
||||||
|
|
||||||
|
struct Ray {
|
||||||
|
t: f32,
|
||||||
|
vox_pos: vec3<f32>,
|
||||||
|
t_inc: vec3<f32>,
|
||||||
|
scale: u32,
|
||||||
|
min_adj: vec3<f32>,
|
||||||
|
child: u32,
|
||||||
|
axis: u32,
|
||||||
|
node_start: u32,
|
||||||
|
group_offset: u32,
|
||||||
|
inv_dir_bits: u32,
|
||||||
|
parents: array<u32, MAX_SCALE>,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RayResult {
|
||||||
|
ray: Ray,
|
||||||
|
data: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RayStart {
|
||||||
|
hit: bool,
|
||||||
|
ray: Ray,
|
||||||
|
normals: mat3x3<f32>,
|
||||||
|
t_mult: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_ray(pos_view: vec4<f32>, dir_view: vec4<f32>) -> RayStart {
|
||||||
|
let gi = 0;
|
||||||
|
let group = voxel_groups[gi];
|
||||||
|
if group.scale == 0 {
|
||||||
|
return RayStart();
|
||||||
|
}
|
||||||
|
let dimensions = vec3<u32>(1u << group.scale);
|
||||||
|
let dim_f = vec3<f32>(dimensions);
|
||||||
|
let dim_i = vec3<i32>(dimensions);
|
||||||
|
|
||||||
|
// transform so that group is at 0,0
|
||||||
|
let pos = (group.transform_inv * pos_view).xyz;
|
||||||
|
var dir = (group.transform_inv * dir_view).xyz;
|
||||||
|
if dir.x == 0 {dir.x = EPSILON;}
|
||||||
|
if dir.y == 0 {dir.y = EPSILON;}
|
||||||
|
if dir.z == 0 {dir.z = EPSILON;}
|
||||||
|
|
||||||
|
let dir_if = sign(dir);
|
||||||
|
let dir_uf = max(dir_if, vec3<f32>(0.0));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// calculate normals
|
||||||
|
var normals = mat3x3<f32>(
|
||||||
|
(group.transform * vec4<f32>(dir_if.x, 0.0, 0.0, 0.0)).xyz,
|
||||||
|
(group.transform * vec4<f32>(0.0, dir_if.y, 0.0, 0.0)).xyz,
|
||||||
|
(group.transform * vec4<f32>(0.0, 0.0, dir_if.z, 0.0)).xyz,
|
||||||
|
);
|
||||||
|
var axis = 0u;
|
||||||
|
|
||||||
|
// find where ray intersects with group
|
||||||
|
let pos_min = (vec3<f32>(1.0) - dir_uf) * dim_f;
|
||||||
|
// time of intersection; x = td + p, solve for t
|
||||||
|
var t_min = (pos_min - pos) / dir;
|
||||||
|
if outside3f(pos, ZERO3F, dim_f) {
|
||||||
|
// points of intersection
|
||||||
|
let px = pos + t_min.x * dir;
|
||||||
|
let py = pos + t_min.y * dir;
|
||||||
|
let pz = pos + t_min.z * dir;
|
||||||
|
|
||||||
|
// check if point is in bounds
|
||||||
|
let hit = vec3<bool>(
|
||||||
|
inside2f(px.yz, ZERO2F, dim_f.yz),
|
||||||
|
inside2f(py.xz, ZERO2F, dim_f.xz),
|
||||||
|
inside2f(pz.xy, ZERO2F, dim_f.xy),
|
||||||
|
) && (t_min > ZERO3F);
|
||||||
|
if !any(hit) {
|
||||||
|
return RayStart();
|
||||||
|
}
|
||||||
|
axis = select(select(2u, 1u, hit.y), 0u, hit.x);
|
||||||
|
}
|
||||||
|
let t_mult = f32(1u << (MAX_SCALE - group.scale));
|
||||||
|
t_min *= t_mult;
|
||||||
|
// time to move 1 unit in each direction
|
||||||
|
let full = f32(1u << MAX_SCALE);
|
||||||
|
let t_inc = abs(1.0 / dir) * full;
|
||||||
|
let t_offset = max(max(t_min.x, t_min.y), t_min.z);
|
||||||
|
let t = max(0.0, t_offset);
|
||||||
|
|
||||||
|
let dir_i = vec3<i32>(dir_if);
|
||||||
|
let dir_u = vec3<u32>((dir_i + vec3<i32>(1)) / 2);
|
||||||
|
let dir_bits = vec_to_dir(dir_u);
|
||||||
|
let inv_dir_bits = 7 - dir_bits;
|
||||||
|
|
||||||
|
let node_start = 1u;
|
||||||
|
let scale = MAX_SCALE - 1;
|
||||||
|
let scale_exp2 = 0.5;
|
||||||
|
let parents = array<u32, MAX_SCALE>();
|
||||||
|
|
||||||
|
var child = 0u;
|
||||||
|
var vox_pos = vec3<f32>(1.0);
|
||||||
|
let t_center = t_min + scale_exp2 * t_inc;
|
||||||
|
if t > t_center.x { vox_pos.x = 1.5; child |= 4u; }
|
||||||
|
if t > t_center.y { vox_pos.y = 1.5; child |= 2u; }
|
||||||
|
if t > t_center.z { vox_pos.z = 1.5; child |= 1u; }
|
||||||
|
let min_adj = t_min - t_inc;
|
||||||
|
|
||||||
|
return RayStart(
|
||||||
|
true,
|
||||||
|
Ray(
|
||||||
|
t,
|
||||||
|
vox_pos,
|
||||||
|
t_inc,
|
||||||
|
scale,
|
||||||
|
min_adj,
|
||||||
|
child,
|
||||||
|
axis,
|
||||||
|
node_start,
|
||||||
|
group.offset,
|
||||||
|
inv_dir_bits,
|
||||||
|
parents,
|
||||||
|
),
|
||||||
|
normals,
|
||||||
|
t_mult,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ray_next(ray: Ray, skip: u32) -> RayResult {
|
||||||
|
let group_offset = ray.group_offset;
|
||||||
|
let t_inc = ray.t_inc;
|
||||||
|
let min_adj = ray.min_adj;
|
||||||
|
let inv_dir_bits = ray.inv_dir_bits;
|
||||||
|
var scale = ray.scale;
|
||||||
|
var scale_exp2 = bitcast<f32>((scale + 127 - MAX_SCALE) << 23);
|
||||||
|
var vox_pos = ray.vox_pos;
|
||||||
|
var t = ray.t;
|
||||||
|
var node_start = ray.node_start;
|
||||||
|
var child = ray.child;
|
||||||
|
var parents = ray.parents;
|
||||||
|
var axis: u32;
|
||||||
|
var data = 0u;
|
||||||
|
loop {
|
||||||
|
let t_corner = vox_pos * t_inc + min_adj;
|
||||||
|
let node = voxels[group_offset + node_start + (child ^ inv_dir_bits)];
|
||||||
|
if node >= LEAF_BIT {
|
||||||
|
if node != skip {
|
||||||
|
data = node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to next time point and determine which axis to move along
|
||||||
|
let t_next = t_corner + scale_exp2 * t_inc;
|
||||||
|
t = min(min(t_next.x, t_next.y), t_next.z);
|
||||||
|
axis = select(select(0u, 1u, t == t_next.y), 2u, t == t_next.z);
|
||||||
|
let move_dir = 4u >> axis;
|
||||||
|
|
||||||
|
// check if need to pop stack
|
||||||
|
if (child & move_dir) > 0 {
|
||||||
|
// calculate new scale; first differing bit after adding
|
||||||
|
let axis_pos = vox_pos[axis];
|
||||||
|
// AWARE
|
||||||
|
let differing = bitcast<u32>(axis_pos) ^ bitcast<u32>(axis_pos + scale_exp2);
|
||||||
|
scale = (bitcast<u32>(f32(differing)) >> 23) - 127 - (23 - MAX_SCALE);
|
||||||
|
scale_exp2 = bitcast<f32>((scale + 127 - MAX_SCALE) << 23);
|
||||||
|
if scale >= MAX_SCALE { break; }
|
||||||
|
|
||||||
|
// restore & recalculate parent
|
||||||
|
let parent_info = parents[scale];
|
||||||
|
node_start = parent_info >> 3;
|
||||||
|
child = parent_info & 7;
|
||||||
|
let scale_vec = vec3<u32>(scale + 23 - MAX_SCALE);
|
||||||
|
// remove bits lower than current scale
|
||||||
|
vox_pos = bitcast<vec3<f32>>((bitcast<vec3<u32>>(vox_pos) >> scale_vec) << scale_vec);
|
||||||
|
}
|
||||||
|
// move to next child and voxel position
|
||||||
|
child += move_dir;
|
||||||
|
vox_pos[axis] += scale_exp2;
|
||||||
|
} else {
|
||||||
|
// push current node to stack
|
||||||
|
parents[scale] = (node_start << 3) + child;
|
||||||
|
scale -= 1u;
|
||||||
|
|
||||||
|
// calculate child node vars
|
||||||
|
scale_exp2 *= 0.5;
|
||||||
|
child = 0u;
|
||||||
|
let t_center = t_corner + scale_exp2 * t_inc;
|
||||||
|
if t > t_center.x { vox_pos.x += scale_exp2; child |= 4u; }
|
||||||
|
if t > t_center.y { vox_pos.y += scale_exp2; child |= 2u; }
|
||||||
|
if t > t_center.z { vox_pos.z += scale_exp2; child |= 1u; }
|
||||||
|
node_start += 8 + node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RayResult(
|
||||||
|
Ray(
|
||||||
|
t,
|
||||||
|
vox_pos,
|
||||||
|
t_inc,
|
||||||
|
scale,
|
||||||
|
min_adj,
|
||||||
|
child,
|
||||||
|
axis,
|
||||||
|
node_start,
|
||||||
|
group_offset,
|
||||||
|
inv_dir_bits,
|
||||||
|
parents,
|
||||||
|
),
|
||||||
|
data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dir_to_vec(bits: u32) -> vec3<u32> {
|
||||||
|
return vec3<u32>(bits >> 2, (bits & 2) >> 1, bits & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vec_to_dir(vec: vec3<u32>) -> u32 {
|
||||||
|
return vec.x * 4 + vec.y * 2 + vec.z * 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_color(id: u32) -> vec4<f32> {
|
||||||
|
switch id {
|
||||||
|
case 0u: {
|
||||||
|
return vec4<f32>(0.0);
|
||||||
|
}
|
||||||
|
case 1u: {
|
||||||
|
return vec4<f32>(0.5, 0.5, 0.5, 1.0);
|
||||||
|
}
|
||||||
|
case 2u: {
|
||||||
|
return vec4<f32>(0.5, 1.0, 0.5, 1.0);
|
||||||
|
}
|
||||||
|
case 3u: {
|
||||||
|
return vec4<f32>(0.5, 0.5, 1.0, 0.5);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outside3f(v: vec3<f32>, low: vec3<f32>, high: vec3<f32>) -> bool {
|
||||||
|
return any(v < low) || any(v > high);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inside2f(v: vec2<f32>, low: vec2<f32>, high: vec2<f32>) -> bool {
|
||||||
|
return all(v >= low) && all(v <= high);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inside3i(v: vec3<i32>, low: vec3<i32>, high: vec3<i32>) -> bool {
|
||||||
|
return all(v >= low) && all(v <= high);
|
||||||
|
}
|
||||||
38
src/client/render/voxel/ray/voxel/shader/render.wgsl
Normal file
38
src/client/render/voxel/ray/voxel/shader/render.wgsl
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Vertex shader
|
||||||
|
|
||||||
|
struct VertexOutput {
|
||||||
|
@builtin(position) clip_position: vec4<f32>,
|
||||||
|
@location(0) tex_pos: vec2<f32>,
|
||||||
|
};
|
||||||
|
|
||||||
|
@group(0) @binding(0)
|
||||||
|
var tex: texture_2d<f32>;
|
||||||
|
@group(0) @binding(1)
|
||||||
|
var sample: sampler;
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vs_main(
|
||||||
|
@builtin(vertex_index) vi: u32,
|
||||||
|
@builtin(instance_index) ii: u32,
|
||||||
|
) -> VertexOutput {
|
||||||
|
var out: VertexOutput;
|
||||||
|
|
||||||
|
let pos = vec2<f32>(
|
||||||
|
f32(vi % 2u),
|
||||||
|
f32(vi / 2u),
|
||||||
|
);
|
||||||
|
out.clip_position = vec4<f32>(pos * 2.0 - 1.0, 0.0, 1.0);
|
||||||
|
out.tex_pos = pos;
|
||||||
|
out.tex_pos.y = 1.0 - out.tex_pos.y;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fragment shader
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn fs_main(
|
||||||
|
in: VertexOutput,
|
||||||
|
) -> @location(0) vec4<f32> {
|
||||||
|
return textureSample(tex, sample, in.tex_pos);
|
||||||
|
}
|
||||||
|
|
||||||
19
src/client/render/voxel/ray/voxel/view.rs
Normal file
19
src/client/render/voxel/ray/voxel/view.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use nalgebra::Transform3;
|
||||||
|
|
||||||
|
#[repr(C, align(16))]
|
||||||
|
#[derive(Clone, Copy, PartialEq, bytemuck::Zeroable)]
|
||||||
|
pub struct View {
|
||||||
|
pub transform: Transform3<f32>,
|
||||||
|
pub zoom: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl bytemuck::Pod for View {}
|
||||||
|
|
||||||
|
impl Default for View {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
zoom: 1.0,
|
||||||
|
transform: Transform3::identity(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,7 +58,7 @@ const ZERO3F = vec3<f32>(0.0);
|
|||||||
const ZERO2F = vec2<f32>(0.0);
|
const ZERO2F = vec2<f32>(0.0);
|
||||||
const FULL_ALPHA = 0.999;
|
const FULL_ALPHA = 0.999;
|
||||||
const EPSILON = 0.00000000001;
|
const EPSILON = 0.00000000001;
|
||||||
const MAX_ITERS = 2000;
|
const MAX_ITERS = 10000;
|
||||||
// NOTE: CANNOT GO HIGHER THAN 23 due to how floating point
|
// NOTE: CANNOT GO HIGHER THAN 23 due to how floating point
|
||||||
// numbers are stored and the bit manipulation used
|
// numbers are stored and the bit manipulation used
|
||||||
const MAX_SCALE: u32 = 13;
|
const MAX_SCALE: u32 = 13;
|
||||||
@@ -166,12 +166,8 @@ fn trace_full(pos_view: vec4<f32>, dir_view: vec4<f32>) -> vec4<f32> {
|
|||||||
}
|
}
|
||||||
var pos = (pos_view + dir_view * real_t).xyz;
|
var pos = (pos_view + dir_view * real_t).xyz;
|
||||||
pos[axis] = round(pos[axis]) - (1.0 - dir_uf[axis]);
|
pos[axis] = round(pos[axis]) - (1.0 - dir_uf[axis]);
|
||||||
// if true {return vec4<f32>(floor(pos) / 16.0, 1.0);}
|
|
||||||
// let pos = (vox_pos - 1.5) * (dir_if) + 0.5 - scale_exp2 * (1.0 - dir_uf);
|
|
||||||
// let pos = t / t_mult;
|
|
||||||
// if true {return vec4<f32>(pos, 1.0);}
|
|
||||||
let vcolor = get_color(node & LEAF_MASK, pos);
|
let vcolor = get_color(node & LEAF_MASK, pos);
|
||||||
let normal = normals[axis];
|
var normal = normals[axis];
|
||||||
let light_color = vec3<f32>(1.0);
|
let light_color = vec3<f32>(1.0);
|
||||||
let light_dir = global_lights[0].dir;
|
let light_dir = global_lights[0].dir;
|
||||||
|
|
||||||
|
|||||||
82
src/client/render_vulkan/command.rs
Normal file
82
src/client/render_vulkan/command.rs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
use crate::{
|
||||||
|
client::camera::Camera,
|
||||||
|
common::component::{ChunkMesh, ChunkPos}, util::oct_tree::OctTree,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{voxel::VoxelColor, Renderer};
|
||||||
|
use bevy_ecs::entity::Entity;
|
||||||
|
use nalgebra::{Rotation3, Vector3};
|
||||||
|
use ndarray::Array3;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum RenderCommand {
|
||||||
|
CreateVoxelGrid(CreateVoxelGrid),
|
||||||
|
AddChunk(AddChunk),
|
||||||
|
UpdateGridTransform(UpdateGridTransform),
|
||||||
|
ViewUpdate(Camera),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct CreateVoxelGrid {
|
||||||
|
pub id: Entity,
|
||||||
|
pub pos: Vector3<f32>,
|
||||||
|
pub orientation: Rotation3<f32>,
|
||||||
|
pub dimensions: Vector3<usize>,
|
||||||
|
pub grid: Array3<VoxelColor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct AddChunk {
|
||||||
|
pub id: Entity,
|
||||||
|
pub pos: ChunkPos,
|
||||||
|
pub mesh: ChunkMesh,
|
||||||
|
pub tree: OctTree,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct UpdateGridTransform {
|
||||||
|
pub id: Entity,
|
||||||
|
pub pos: Vector3<f32>,
|
||||||
|
pub orientation: Rotation3<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Renderer {
|
||||||
|
pub fn handle_commands(&mut self, commands: Vec<RenderCommand>) {
|
||||||
|
let mut new_camera = false;
|
||||||
|
for cmd in commands {
|
||||||
|
match cmd {
|
||||||
|
RenderCommand::CreateVoxelGrid(desc) => self.voxel_pipeline.add_group(
|
||||||
|
&self.device,
|
||||||
|
&mut self.encoder,
|
||||||
|
&mut self.staging_belt,
|
||||||
|
desc,
|
||||||
|
),
|
||||||
|
RenderCommand::ViewUpdate(camera) => {
|
||||||
|
new_camera = true;
|
||||||
|
self.camera = camera;
|
||||||
|
}
|
||||||
|
RenderCommand::UpdateGridTransform(update) => self.voxel_pipeline.update_transform(
|
||||||
|
&self.device,
|
||||||
|
&mut self.encoder,
|
||||||
|
&mut self.staging_belt,
|
||||||
|
update,
|
||||||
|
),
|
||||||
|
RenderCommand::AddChunk(desc) => self.voxel_pipeline.add_chunk(
|
||||||
|
&self.device,
|
||||||
|
&mut self.encoder,
|
||||||
|
&mut self.staging_belt,
|
||||||
|
desc,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if new_camera {
|
||||||
|
self.voxel_pipeline.update_view(
|
||||||
|
&self.device,
|
||||||
|
&mut self.encoder,
|
||||||
|
&mut self.staging_belt,
|
||||||
|
self.size,
|
||||||
|
&self.camera,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
79
src/client/render_vulkan/mod.rs
Normal file
79
src/client/render_vulkan/mod.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
mod command;
|
||||||
|
pub mod voxel;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub use command::*;
|
||||||
|
use vulkano::{
|
||||||
|
device::{Device, DeviceCreateInfo, QueueCreateInfo, QueueFlags}, instance::{Instance, InstanceCreateInfo}, memory::allocator::StandardMemoryAllocator, VulkanLibrary
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::camera::Camera;
|
||||||
|
use crate::client::rsc::CLEAR_COLOR;
|
||||||
|
use nalgebra::Vector2;
|
||||||
|
use voxel::VoxelPipeline;
|
||||||
|
use winit::{dpi::PhysicalSize, window::Window};
|
||||||
|
|
||||||
|
pub struct Renderer {
|
||||||
|
camera: Camera,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Renderer {
|
||||||
|
pub fn new(window: Arc<Window>) -> Self {
|
||||||
|
let library = VulkanLibrary::new().expect("no local Vulkan library/DLL");
|
||||||
|
let instance = Instance::new(library, InstanceCreateInfo::default())
|
||||||
|
.expect("failed to create instance");
|
||||||
|
let physical_device = instance
|
||||||
|
.enumerate_physical_devices()
|
||||||
|
.expect("could not enumerate devices")
|
||||||
|
.next()
|
||||||
|
.expect("no devices available");
|
||||||
|
let queue_family_index = physical_device
|
||||||
|
.queue_family_properties()
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.position(|(_queue_family_index, queue_family_properties)| {
|
||||||
|
queue_family_properties
|
||||||
|
.queue_flags
|
||||||
|
.contains(QueueFlags::GRAPHICS)
|
||||||
|
})
|
||||||
|
.expect("couldn't find a graphical queue family")
|
||||||
|
as u32;
|
||||||
|
|
||||||
|
let (device, mut queues) = Device::new(
|
||||||
|
physical_device,
|
||||||
|
DeviceCreateInfo {
|
||||||
|
// here we pass the desired queue family to use by index
|
||||||
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("failed to create device");
|
||||||
|
|
||||||
|
let queue = queues.next().unwrap();
|
||||||
|
let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone()));
|
||||||
|
|
||||||
|
Self {
|
||||||
|
camera: Camera::default(),
|
||||||
|
size: Vector2::new(size.width, size.height),
|
||||||
|
voxel_pipeline: VoxelPipeline::new(&device, &config),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset_shader(&mut self) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_shader(&mut self) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(&mut self) {}
|
||||||
|
|
||||||
|
pub fn resize(&mut self, size: PhysicalSize<u32>) {
|
||||||
|
self.size = Vector2::new(size.width, size.height);
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/client/render_vulkan/voxel/mod.rs
Normal file
25
src/client/render_vulkan/voxel/mod.rs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use vulkano::{buffer::{Buffer, BufferCreateInfo, BufferUsage}, memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryTypeFilter}};
|
||||||
|
|
||||||
|
pub struct VoxelPipeline {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VoxelPipeline {
|
||||||
|
pub fn init(memory_allocator: Arc<impl MemoryAllocator>) {
|
||||||
|
let buffer = Buffer::from_data(
|
||||||
|
memory_allocator.clone(),
|
||||||
|
BufferCreateInfo {
|
||||||
|
usage: BufferUsage::UNIFORM_BUFFER,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
AllocationCreateInfo {
|
||||||
|
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE
|
||||||
|
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,8 +3,9 @@ use std::collections::{HashMap, HashSet};
|
|||||||
use bevy_ecs::{entity::Entity, system::Commands};
|
use bevy_ecs::{entity::Entity, system::Commands};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::component::{ChunkBundle, ChunkData, ChunkMesh, ChunkPos}, server::generation::generate_tree, util::
|
common::component::{ChunkBundle, ChunkData, ChunkMesh, ChunkPos},
|
||||||
thread::{ExitType, ThreadChannel, ThreadHandle}
|
server::generation::generate_tree,
|
||||||
|
util::{oct_tree::OctTree, thread::{ExitType, ThreadChannel, ThreadHandle}},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct ChunkManager {
|
pub struct ChunkManager {
|
||||||
@@ -107,7 +108,14 @@ fn chunk_loader_main(channel: ThreadChannel<ServerChunkMsg, ChunkLoaderMsg>) {
|
|||||||
let tree = ChunkData::from_tree(generate_tree(pos));
|
let tree = ChunkData::from_tree(generate_tree(pos));
|
||||||
let tree_time = std::time::Instant::now() - start;
|
let tree_time = std::time::Instant::now() - start;
|
||||||
|
|
||||||
println!("gen time: {:<5?}; size: {}", tree_time, tree.raw().len());
|
// let worst = OctTree::from_fn(f_leaf, f_node, levels);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"gen time: {:<5?}; size: {} nodes = {} bytes",
|
||||||
|
tree_time,
|
||||||
|
tree.raw().len(),
|
||||||
|
std::mem::size_of_val(tree.raw())
|
||||||
|
);
|
||||||
|
|
||||||
channel.send(ServerChunkMsg::ChunkGenerated(GeneratedChunk {
|
channel.send(ServerChunkMsg::ChunkGenerated(GeneratedChunk {
|
||||||
pos,
|
pos,
|
||||||
@@ -121,4 +129,3 @@ fn chunk_loader_main(channel: ThreadChannel<ServerChunkMsg, ChunkLoaderMsg>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
mod load;
|
|
||||||
pub use load::*;
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
use fastnoise_simd::FastNoiseSIMD;
|
||||||
use nalgebra::Vector3;
|
use nalgebra::Vector3;
|
||||||
use simdnoise::NoiseBuilder;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::component::{chunk, ChunkPos},
|
common::component::{chunk, ChunkPos},
|
||||||
@@ -11,11 +11,11 @@ pub fn generate_tree(pos: ChunkPos) -> OctTree {
|
|||||||
return OctTree::from_leaf(0, 8);
|
return OctTree::from_leaf(0, 8);
|
||||||
}
|
}
|
||||||
let posf: Vector3<f32> = pos.cast() * chunk::SIDE_LENGTH as f32;
|
let posf: Vector3<f32> = pos.cast() * chunk::SIDE_LENGTH as f32;
|
||||||
let noise1 = generate_noise_map(0, 1.0, posf, chunk::SCALE, &mut |v: f32| {
|
let noise1 = generate_noise_map(2, 1.0, posf, chunk::SCALE, &mut |v: f32| {
|
||||||
(v * 2.0).exp2() * TOP * 0.25
|
(v * 2.0).exp2() * TOP * 0.25
|
||||||
});
|
});
|
||||||
let noise2 = generate_noise_map(1, 50.0, posf, chunk::SCALE, &mut |v: f32| v * 20.0 + GRASS);
|
let noise2 = generate_noise_map(0, 50.0, posf, chunk::SCALE, &mut |v: f32| v * 20.0 + GRASS);
|
||||||
OctTree::from_fn_rec(
|
OctTree::from_fn(
|
||||||
&mut |p| generate_leaf(p, posf, (&noise1.base, &noise2.base)),
|
&mut |p| generate_leaf(p, posf, (&noise1.base, &noise2.base)),
|
||||||
&mut |p, lvl| generate_node(p, lvl, posf, (&noise1, &noise2)),
|
&mut |p, lvl| generate_node(p, lvl, posf, (&noise1, &noise2)),
|
||||||
chunk::SCALE,
|
chunk::SCALE,
|
||||||
@@ -89,10 +89,15 @@ fn generate_noise_map(
|
|||||||
adjust: &mut impl FnMut(f32) -> f32,
|
adjust: &mut impl FnMut(f32) -> f32,
|
||||||
) -> NoiseMap {
|
) -> NoiseMap {
|
||||||
let mut size = 2usize.pow(levels);
|
let mut size = 2usize.pow(levels);
|
||||||
let (mut base, min, max) = NoiseBuilder::gradient_2d_offset(posf.x, size, posf.z, size)
|
let posi = Vector3::new(posf.x as i32, posf.y as i32, posf.z as i32);
|
||||||
.with_seed(seed)
|
let noise = FastNoiseSIMD::new(seed).get_simplex_set(posi.x, posi.y, posi.z, size as i32, size as i32, 1, freq * 150.0 / size as f32);
|
||||||
.with_freq(freq / (size as f32))
|
let mut base = noise.as_vec();
|
||||||
.generate();
|
let (mut min, mut max) = (f32::MAX, f32::MIN);
|
||||||
|
for v in &base {
|
||||||
|
min = v.min(min);
|
||||||
|
max = v.max(max);
|
||||||
|
}
|
||||||
|
println!("{min}, {max}");
|
||||||
for v in &mut base {
|
for v in &mut base {
|
||||||
*v = adjust((*v - min) / (max - min));
|
*v = adjust((*v - min) / (max - min));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,13 @@ impl OctNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type OctNodeMap = FxHashMap<[OctNode; 8], OctNode>;
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
struct OctNodeEntry {
|
||||||
|
pub node: OctNode,
|
||||||
|
pub count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
type OctNodeMap = FxHashMap<[OctNode; 8], OctNodeEntry>;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct OctTree {
|
pub struct OctTree {
|
||||||
@@ -61,7 +67,10 @@ impl OctTree {
|
|||||||
levels,
|
levels,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn from_fn_rec(
|
pub fn from_leaf_fn(f_leaf: &mut impl FnMut(Vector3<usize>) -> u32, levels: u32) -> OctTree {
|
||||||
|
Self::from_fn(f_leaf, &mut |_, _| None, levels)
|
||||||
|
}
|
||||||
|
pub fn from_fn(
|
||||||
f_leaf: &mut impl FnMut(Vector3<usize>) -> u32,
|
f_leaf: &mut impl FnMut(Vector3<usize>) -> u32,
|
||||||
f_node: &mut impl FnMut(Vector3<usize>, u32) -> Option<u32>,
|
f_node: &mut impl FnMut(Vector3<usize>, u32) -> Option<u32>,
|
||||||
levels: u32,
|
levels: u32,
|
||||||
@@ -102,8 +111,9 @@ impl OctTree {
|
|||||||
core::array::from_fn(|i| OctNode::new_leaf(f_leaf(offset + CORNERS[i])));
|
core::array::from_fn(|i| OctNode::new_leaf(f_leaf(offset + CORNERS[i])));
|
||||||
if leaves[1..].iter().all(|l| *l == leaves[0]) {
|
if leaves[1..].iter().all(|l| *l == leaves[0]) {
|
||||||
data.push(leaves[0]);
|
data.push(leaves[0]);
|
||||||
} else if let Some(node) = map.get(&leaves) {
|
} else if let Some(entry) = map.get_mut(&leaves) {
|
||||||
data.push(*node);
|
data.push(entry.node);
|
||||||
|
entry.count += 1;
|
||||||
} else {
|
} else {
|
||||||
data.extend_from_slice(&leaves);
|
data.extend_from_slice(&leaves);
|
||||||
}
|
}
|
||||||
@@ -128,7 +138,10 @@ impl OctTree {
|
|||||||
let node = OctNode::new_node(sub_start as u32);
|
let node = OctNode::new_node(sub_start as u32);
|
||||||
data[i + j] = node;
|
data[i + j] = node;
|
||||||
data_start += len;
|
data_start += len;
|
||||||
map.insert(data[sub_start..sub_start+8].try_into().unwrap(), node);
|
map.insert(
|
||||||
|
data[sub_start..sub_start + 8].try_into().unwrap(),
|
||||||
|
OctNodeEntry { node, count: 1 },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,14 +150,15 @@ impl OctTree {
|
|||||||
if first.is_leaf() && data[i + 1..i + 8].iter().all(|l| *l == first) {
|
if first.is_leaf() && data[i + 1..i + 8].iter().all(|l| *l == first) {
|
||||||
data.truncate(i);
|
data.truncate(i);
|
||||||
data.push(first);
|
data.push(first);
|
||||||
} else if let Some(node) = map.get(&data[i..i + 8]) {
|
} else if let Some(entry) = map.get_mut(&data[i..i + 8]) {
|
||||||
data.truncate(i);
|
data.truncate(i);
|
||||||
data.push(*node);
|
data.push(entry.node);
|
||||||
|
entry.count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn from_arr(arr: ArrayView3<u32>, levels: u32) -> Self {
|
pub fn from_arr(arr: ArrayView3<u32>, levels: u32) -> Self {
|
||||||
Self::from_fn_rec(&mut |p| arr[(p.x, p.y, p.z)], &mut |_, _| None, levels)
|
Self::from_fn(&mut |p| arr[(p.x, p.y, p.z)], &mut |_, _| None, levels)
|
||||||
}
|
}
|
||||||
pub fn get(&self, mut pos: Vector3<usize>) -> u32 {
|
pub fn get(&self, mut pos: Vector3<usize>) -> u32 {
|
||||||
let mut data_start = 1;
|
let mut data_start = 1;
|
||||||
@@ -164,7 +178,6 @@ impl OctTree {
|
|||||||
pub fn raw(&self) -> &[OctNode] {
|
pub fn raw(&self) -> &[OctNode] {
|
||||||
&self.data
|
&self.data
|
||||||
}
|
}
|
||||||
pub fn mesh(&self) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OctTreeIter<'a> {
|
pub struct OctTreeIter<'a> {
|
||||||
|
|||||||
Reference in New Issue
Block a user