From 54010cb44118673aec2c49055d50ecc465dee11a Mon Sep 17 00:00:00 2001 From: Capucho Date: Sun, 13 Sep 2020 11:03:42 +0100 Subject: [PATCH] Finished porting all pipelines --- Cargo.lock | 520 ++--- voxygen/src/render/error.rs | 2 +- voxygen/src/render/mod.rs | 9 +- voxygen/src/render/pipelines/figure.rs | 196 +- voxygen/src/render/pipelines/fluid.rs | 179 +- voxygen/src/render/pipelines/lod_terrain.rs | 128 +- voxygen/src/render/pipelines/mod.rs | 229 +- voxygen/src/render/pipelines/particle.rs | 186 +- voxygen/src/render/pipelines/postprocess.rs | 162 +- voxygen/src/render/pipelines/shadow.rs | 233 +- voxygen/src/render/pipelines/skybox.rs | 126 +- voxygen/src/render/pipelines/sprite.rs | 235 +- voxygen/src/render/pipelines/terrain.rs | 192 +- voxygen/src/render/pipelines/ui.rs | 181 +- voxygen/src/render/renderer.rs | 2197 ++++++++++--------- 15 files changed, 2953 insertions(+), 1822 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12ff98449d..199695bf21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,12 +100,6 @@ dependencies = [ "xml-rs", ] -[[package]] -name = "android_glue" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" - [[package]] name = "ansi-parser" version = "0.7.0" @@ -217,11 +211,11 @@ dependencies = [ [[package]] name = "ash" -version = "0.31.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c69a8137596e84c22d57f3da1b5de1d4230b1742a710091c85f4d7ce50f00f38" +checksum = "06063a002a77d2734631db74e8f4ce7148b77fe522e6bca46f2ae7774fd48112" dependencies = [ - "libloading 0.6.7", + "libloading 0.7.0", ] [[package]] @@ -536,13 +530,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "cgl" -version = "0.3.2" +name = "cfg_aliases" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" -dependencies = [ - "libc", -] +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "chrono" @@ -671,22 +662,6 @@ dependencies = [ "cc", ] -[[package]] -name = "cocoa" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54201c07dcf3a5ca33fececb8042aed767ee4bfd5a0235a8ceabcda956044b2" -dependencies = [ - "bitflags", - "block", - "cocoa-foundation", - "core-foundation 0.9.1", - "core-graphics 0.22.2", - "foreign-types", - "libc", - "objc", -] - [[package]] name = "cocoa" version = "0.24.0" @@ -718,6 +693,16 @@ dependencies = [ "objc", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -1252,11 +1237,10 @@ dependencies = [ [[package]] name = "d3d12" version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a60cceb22c7c53035f8980524fdc7f17cf49681a3c154e6757d30afbec6ec4" +source = "git+https://github.com/gfx-rs/d3d12-rs?rev=be19a243b86e0bafb9937d661fc8eabb3e42b44e#be19a243b86e0bafb9937d661fc8eabb3e42b44e" dependencies = [ "bitflags", - "libloading 0.6.7", + "libloading 0.7.0", "winapi 0.3.9", ] @@ -1266,7 +1250,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9293a0da7d1bc1f30090ece4d9f9de79a07be7302ddb00e5eb1fefb6ee6409e2" dependencies = [ - "petgraph", + "petgraph 0.4.13", ] [[package]] @@ -1466,15 +1450,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" -[[package]] -name = "draw_state" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33cf9537e2d06891448799b96d5a8c8083e0e90522a7fdabe6ebf4f41d79d651" -dependencies = [ - "bitflags", -] - [[package]] name = "either" version = "1.6.1" @@ -1627,6 +1602,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" +[[package]] +name = "fixedbitset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" + [[package]] name = "flate2" version = "1.0.20" @@ -1911,22 +1892,10 @@ dependencies = [ "wasi 0.10.2+wasi-snapshot-preview1", ] -[[package]] -name = "gfx" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01de46f9508a5c259aef105f0bff760ceddca832ea9c87ce03d1923e22ee155b" -dependencies = [ - "draw_state", - "gfx_core", - "log", -] - [[package]] name = "gfx-auxil" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cd956b592970f08545b9325b87580eb95a51843b6f39da27b8667fec1a1216" +version = "0.8.0" +source = "git+https://github.com/gfx-rs/gfx?rev=69991710a968e1e846148cdba425077e00b6febe#69991710a968e1e846148cdba425077e00b6febe" dependencies = [ "fxhash", "gfx-hal", @@ -1935,15 +1904,14 @@ dependencies = [ [[package]] name = "gfx-backend-dx11" -version = "0.6.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b43f06089866bdffe59b5a6801022c86b74d2c1dd28940a9cf301d3d014fbc" +version = "0.7.0" +source = "git+https://github.com/gfx-rs/gfx?rev=69991710a968e1e846148cdba425077e00b6febe#69991710a968e1e846148cdba425077e00b6febe" dependencies = [ "arrayvec", "bitflags", "gfx-auxil", "gfx-hal", - "libloading 0.6.7", + "libloading 0.7.0", "log", "parking_lot 0.11.1", "range-alloc", @@ -1957,9 +1925,8 @@ dependencies = [ [[package]] name = "gfx-backend-dx12" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375014deed24d76b03604736dd899f0925158a1a96db90cbefb9cce070f71af7" +version = "0.7.0" +source = "git+https://github.com/gfx-rs/gfx?rev=69991710a968e1e846148cdba425077e00b6febe#69991710a968e1e846148cdba425077e00b6febe" dependencies = [ "arrayvec", "bit-set", @@ -1968,29 +1935,50 @@ dependencies = [ "gfx-auxil", "gfx-hal", "log", + "parking_lot 0.11.1", "range-alloc", "raw-window-handle", "smallvec", "spirv_cross", + "thunderdome", "winapi 0.3.9", ] [[package]] name = "gfx-backend-empty" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2085227c12b78f6657a900c829f2d0deb46a9be3eaf86844fde263cdc218f77c" +version = "0.7.0" +source = "git+https://github.com/gfx-rs/gfx?rev=69991710a968e1e846148cdba425077e00b6febe#69991710a968e1e846148cdba425077e00b6febe" dependencies = [ "gfx-hal", "log", "raw-window-handle", ] +[[package]] +name = "gfx-backend-gl" +version = "0.7.0" +source = "git+https://github.com/gfx-rs/gfx?rev=69991710a968e1e846148cdba425077e00b6febe#69991710a968e1e846148cdba425077e00b6febe" +dependencies = [ + "arrayvec", + "bitflags", + "fxhash", + "gfx-hal", + "glow", + "js-sys", + "khronos-egl", + "libloading 0.7.0", + "log", + "naga", + "parking_lot 0.11.1", + "raw-window-handle", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gfx-backend-metal" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "273d60d5207f96d99e0d11d0718995f67e56533a9df1444d83baf787f4c3cb32" +version = "0.7.0" +source = "git+https://github.com/gfx-rs/gfx?rev=69991710a968e1e846148cdba425077e00b6febe#69991710a968e1e846148cdba425077e00b6febe" dependencies = [ "arrayvec", "bitflags", @@ -1998,25 +1986,23 @@ dependencies = [ "cocoa-foundation", "copyless", "foreign-types", - "gfx-auxil", + "fxhash", "gfx-hal", - "lazy_static", "log", "metal", + "naga", "objc", "parking_lot 0.11.1", + "profiling", "range-alloc", "raw-window-handle", - "smallvec", - "spirv_cross", "storage-map", ] [[package]] name = "gfx-backend-vulkan" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3a63cf61067a09b7d1ac480af3cb2ae0c5ede5bed294607bbd814cb1666c45" +version = "0.7.0" +source = "git+https://github.com/gfx-rs/gfx?rev=69991710a968e1e846148cdba425077e00b6febe#69991710a968e1e846148cdba425077e00b6febe" dependencies = [ "arrayvec", "ash", @@ -2024,79 +2010,24 @@ dependencies = [ "core-graphics-types", "gfx-hal", "inplace_it", - "lazy_static", "log", + "naga", "objc", + "parking_lot 0.11.1", "raw-window-handle", "smallvec", "winapi 0.3.9", - "x11", -] - -[[package]] -name = "gfx-descriptor" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8c7afcd000f279d541a490e27117e61037537279b9342279abf4938fe60c6b" -dependencies = [ - "arrayvec", - "fxhash", - "gfx-hal", - "log", ] [[package]] name = "gfx-hal" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d0754f5b7a43915fd7466883b2d1bb0800d7cc4609178d0b27bf143b9e5123" +version = "0.7.0" +source = "git+https://github.com/gfx-rs/gfx?rev=69991710a968e1e846148cdba425077e00b6febe#69991710a968e1e846148cdba425077e00b6febe" dependencies = [ "bitflags", + "naga", "raw-window-handle", -] - -[[package]] -name = "gfx-memory" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dccdda5d2b39412f4ca2cb15c70b5a82783a86b0606f5e985342754c8ed88f05" -dependencies = [ - "bit-set", - "fxhash", - "gfx-hal", - "log", - "slab", -] - -[[package]] -name = "gfx_core" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75fbddaef2e12b4995900539d7209d947b988a3d87ee8737484d049b526e5441" -dependencies = [ - "bitflags", - "draw_state", - "log", -] - -[[package]] -name = "gfx_device_gl" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c385fa380c18888633aa27d1e16cbae518469702a2f69dcb5f52d5378bebc" -dependencies = [ - "gfx_core", - "gfx_gl", - "log", -] - -[[package]] -name = "gfx_gl" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d38164670920cfb7491bc0cf6f49f0554bd1c44cdbedc6c78d2bf91691ff5e" -dependencies = [ - "gl_generator", + "thiserror", ] [[package]] @@ -2165,17 +2096,6 @@ dependencies = [ "url", ] -[[package]] -name = "gl_generator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" -dependencies = [ - "khronos_api", - "log", - "xml-rs", -] - [[package]] name = "glam" version = "0.10.2" @@ -2192,85 +2112,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] -name = "glsl-include" -version = "0.3.1" +name = "glow" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa2afb1631e7ab4543e0dde0e3fc68bb49c58fee89c07f30a26553b1f684ab6" +checksum = "072136d2c3783f3a92f131acb227bc806d3886278e2a4dc1e9990ec89ef9e70b" dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "glutin" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae1cbb9176b9151c4ce03f012e3cd1c6c18c4be79edeaeb3d99f5d8085c5fa3" -dependencies = [ - "android_glue", - "cgl", - "cocoa 0.23.0", - "core-foundation 0.9.1", - "glutin_egl_sys", - "glutin_emscripten_sys", - "glutin_gles2_sys", - "glutin_glx_sys", - "glutin_wgl_sys", - "lazy_static", - "libloading 0.6.7", - "log", - "objc", - "osmesa-sys", - "parking_lot 0.11.1", - "wayland-client 0.28.5", - "wayland-egl", - "winapi 0.3.9", - "winit", -] - -[[package]] -name = "glutin_egl_sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2abb6aa55523480c4adc5a56bbaa249992e2dddb2fc63dc96e04a3355364c211" -dependencies = [ - "gl_generator", - "winapi 0.3.9", -] - -[[package]] -name = "glutin_emscripten_sys" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80de4146df76e8a6c32b03007bc764ff3249dcaeb4f675d68a06caf1bac363f1" - -[[package]] -name = "glutin_gles2_sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094e708b730a7c8a1954f4f8a31880af00eb8a1c5b5bf85d28a0a3c6d69103" -dependencies = [ - "gl_generator", - "objc", -] - -[[package]] -name = "glutin_glx_sys" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e393c8fc02b807459410429150e9c4faffdb312d59b8c038566173c81991351" -dependencies = [ - "gl_generator", - "x11-dl", -] - -[[package]] -name = "glutin_wgl_sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5951a1569dbab865c6f2a863efafff193a93caf05538d193e9e3816d21696" -dependencies = [ - "gl_generator", + "js-sys", + "slotmap 0.4.0", + "wasm-bindgen", + "web-sys", ] [[package]] @@ -2312,6 +2162,43 @@ dependencies = [ "xi-unicode", ] +[[package]] +name = "gpu-alloc" +version = "0.4.2" +source = "git+https://github.com/zakarumych/gpu-alloc.git?rev=2cd1ad650cdd24d1647b6041f77ced0cbf1ff2a6#2cd1ad650cdd24d1647b6041f77ced0cbf1ff2a6" +dependencies = [ + "bitflags", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.2.1" +source = "git+https://github.com/zakarumych/gpu-alloc.git?rev=2cd1ad650cdd24d1647b6041f77ced0cbf1ff2a6#2cd1ad650cdd24d1647b6041f77ced0cbf1ff2a6" +dependencies = [ + "bitflags", +] + +[[package]] +name = "gpu-descriptor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a70f1e87a3840ed6a3e99e02c2b861e4dbdf26f0d07e38f42ea5aff46cfce2" +dependencies = [ + "bitflags", + "gpu-descriptor-types", + "hashbrown", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126" +dependencies = [ + "bitflags", +] + [[package]] name = "guillotiere" version = "0.6.0" @@ -2764,10 +2651,14 @@ dependencies = [ ] [[package]] -name = "khronos_api" -version = "3.1.0" +name = "khronos-egl" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" +dependencies = [ + "libc", + "libloading 0.7.0", +] [[package]] name = "lazy-bytes-cast" @@ -3061,9 +2952,8 @@ dependencies = [ [[package]] name = "metal" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4e8a431536529327e28c9ba6992f2cb0c15d4222f0602a16e6d7695ff3bccf" +version = "0.21.0" +source = "git+https://github.com/gfx-rs/metal-rs?rev=78f632d194c7c16d18b71d7373c4080847d110b0#78f632d194c7c16d18b71d7373c4080847d110b0" dependencies = [ "bitflags", "block", @@ -3190,14 +3080,16 @@ checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" [[package]] name = "naga" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0873deb76cf44b7454fba7b2ba6a89d3de70c08aceffd2c489379b3d9d08e661" +version = "0.3.1" +source = "git+https://github.com/gfx-rs/naga?tag=gfx-22#9cd6fd9c205a57824644d0baedc6c15997be1e36" dependencies = [ + "bit-set", "bitflags", + "codespan-reporting", "fxhash", "log", "num-traits", + "petgraph 0.5.1", "spirv_headers", "thiserror", ] @@ -3208,7 +3100,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d689b01017db3e350e0e9798d233cca9ad3bf810e7c02b9b55ec06b9ee7dbd8a" dependencies = [ - "cocoa 0.24.0", + "cocoa", "dirs-next", "objc", "objc-foundation", @@ -3722,17 +3614,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "old_school_gfx_glutin_ext" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "450a2a0e6805771787b965af9a552581c9dfc588dc33761c1be690117cd792e1" -dependencies = [ - "gfx_core", - "gfx_device_gl", - "glutin", -] - [[package]] name = "once_cell" version = "1.7.2" @@ -3797,15 +3678,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "osmesa-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" -dependencies = [ - "shared_library", -] - [[package]] name = "owned_ttf_parser" version = "0.6.0" @@ -3901,7 +3773,17 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" dependencies = [ - "fixedbitset", + "fixedbitset 0.1.9", +] + +[[package]] +name = "petgraph" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" +dependencies = [ + "fixedbitset 0.2.0", + "indexmap", ] [[package]] @@ -4086,6 +3968,12 @@ dependencies = [ "unicode-xid 0.2.1", ] +[[package]] +name = "profiling" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c71198452babfbba7419e716d29853c462d59da73c41485ab7dc8b4dc0c4be" + [[package]] name = "prometheus" version = "0.12.0" @@ -4249,8 +4137,7 @@ dependencies = [ [[package]] name = "range-alloc" version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6" +source = "git+https://github.com/gfx-rs/gfx?rev=69991710a968e1e846148cdba425077e00b6febe#69991710a968e1e846148cdba425077e00b6febe" [[package]] name = "raw-window-handle" @@ -4784,6 +4671,26 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +[[package]] +name = "shaderc" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50b8aeaae10b9bda5cba66736a7e265f67698e912e1cc6a4678acba286e22be9" +dependencies = [ + "libc", + "shaderc-sys", +] + +[[package]] +name = "shaderc-sys" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b12d7c62d6732884c9dfab587503fa3a795b108df152415a89da23812d4737e" +dependencies = [ + "cmake", + "libc", +] + [[package]] name = "sharded-slab" version = "0.1.1" @@ -4793,16 +4700,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shared_library" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" -dependencies = [ - "lazy_static", - "libc", -] - [[package]] name = "shellexpand" version = "2.1.0" @@ -4892,6 +4789,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +[[package]] +name = "slotmap" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c46a3482db8f247956e464d783693ece164ca056e6e67563ee5505bdb86452cd" + [[package]] name = "slotmap" version = "1.0.3" @@ -5000,9 +4903,9 @@ dependencies = [ [[package]] name = "spirv_cross" -version = "0.22.2" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ebd49af36be83ecd6290b57147e2a0e26145b832634b17146d934b197ca3713" +checksum = "60647fadbf83c4a72f0d7ea67a7ca3a81835cf442b8deae5c134c3e0055b2e14" dependencies = [ "cc", "js-sys", @@ -5592,12 +5495,6 @@ dependencies = [ "nom 5.1.2", ] -[[package]] -name = "typed-arena" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae" - [[package]] name = "typenum" version = "1.13.0" @@ -5776,7 +5673,7 @@ dependencies = [ "serde_json", "serde_repr", "slab", - "slotmap", + "slotmap 1.0.3", "specs", "specs-idvs", "spin_sleep", @@ -6032,13 +5929,8 @@ dependencies = [ "enum-iterator", "euc", "futures", - "gfx", - "gfx_device_gl", - "gfx_gl", "gilrs", "git2", - "glsl-include", - "glutin", "glyph_brush", "guillotiere", "hashbrown", @@ -6052,12 +5944,12 @@ dependencies = [ "native-dialog", "num 0.4.0", "num_cpus", - "old_school_gfx_glutin_ext", "ordered-float 2.1.1", "rand 0.8.3", "rodio", "ron", "serde", + "shaderc", "specs", "specs-idvs", "strum", @@ -6551,16 +6443,6 @@ dependencies = [ "xcursor", ] -[[package]] -name = "wayland-egl" -version = "0.28.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9461a67930ec16da7a4fd8b50e9ffa23f4417240b43ec84008bd1b2c94421c94" -dependencies = [ - "wayland-client 0.28.5", - "wayland-sys 0.28.5", -] - [[package]] name = "wayland-protocols" version = "0.27.0" @@ -6629,9 +6511,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.48" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b" +checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" dependencies = [ "js-sys", "wasm-bindgen", @@ -6659,20 +6541,17 @@ dependencies = [ [[package]] name = "wgpu" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991903e4c9f5b7319732b30a3d0339e27a51ea992cea22769b5f6c7f7076af6d" +version = "0.7.0" +source = "git+https://github.com/gfx-rs/wgpu-rs.git#1806a5bd4d0a8740774969c92f51ad9a906a2e24" dependencies = [ "arrayvec", - "futures", - "gfx-backend-vulkan", "js-sys", - "objc", + "log", + "naga", "parking_lot 0.11.1", + "profiling", "raw-window-handle", "smallvec", - "tracing", - "typed-arena", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -6682,36 +6561,37 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea487deeae90e06d77eb8e6cef945247774e7c0a0a226d238b31e90633594365" +version = "0.7.0" +source = "git+https://github.com/gfx-rs/wgpu?rev=523ef2dfec0bf18c696bc53fea252fd6fa7350c6#523ef2dfec0bf18c696bc53fea252fd6fa7350c6" dependencies = [ "arrayvec", "bitflags", + "cfg_aliases", "copyless", "fxhash", "gfx-backend-dx11", "gfx-backend-dx12", "gfx-backend-empty", + "gfx-backend-gl", "gfx-backend-metal", "gfx-backend-vulkan", - "gfx-descriptor", "gfx-hal", - "gfx-memory", + "gpu-alloc", + "gpu-descriptor", + "log", "naga", "parking_lot 0.11.1", + "profiling", "raw-window-handle", "smallvec", "thiserror", - "tracing", "wgpu-types", ] [[package]] name = "wgpu-types" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e3529528e608b54838ee618c3923b0f46e6db0334cfc6c42a16cf4ceb3bdb57" +version = "0.7.0" +source = "git+https://github.com/gfx-rs/wgpu?rev=523ef2dfec0bf18c696bc53fea252fd6fa7350c6#523ef2dfec0bf18c696bc53fea252fd6fa7350c6" dependencies = [ "bitflags", ] @@ -6810,7 +6690,7 @@ version = "0.24.0" source = "git+https://gitlab.com/veloren/winit.git?branch=macos-test-spiffed#488c511802dfd95ca54f6f76a38547c93c7b02c9" dependencies = [ "bitflags", - "cocoa 0.24.0", + "cocoa", "core-foundation 0.9.1", "core-graphics 0.22.2", "core-video-sys", @@ -6872,16 +6752,6 @@ dependencies = [ "tap", ] -[[package]] -name = "x11" -version = "2.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ecd092546cb16f25783a5451538e73afc8d32e242648d54f4ae5459ba1e773" -dependencies = [ - "libc", - "pkg-config", -] - [[package]] name = "x11-clipboard" version = "0.5.1" diff --git a/voxygen/src/render/error.rs b/voxygen/src/render/error.rs index c003634999..874965e9b0 100644 --- a/voxygen/src/render/error.rs +++ b/voxygen/src/render/error.rs @@ -8,7 +8,7 @@ pub enum RenderError { CustomError(String), CouldNotFindAdapter, ErrorInitializingCompiler, - ShaderError(shaderc::Error) + ShaderError(shaderc::Error), } impl From for RenderError { diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index 90af9e9ef3..11067697ae 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -18,20 +18,23 @@ pub use self::{ model::{Model, SubModel}, pipelines::{ clouds::{create_mesh as create_clouds_mesh, Locals as CloudsLocals}, - figure::{BoneData as FigureBoneData, BoneMeshes, FigureModel, Locals as FigureLocals}, + figure::{ + BoneData as FigureBoneData, BoneMeshes, FigureLayout, FigureModel, + Locals as FigureLocals, + }, lod_terrain::LodData, particle::Instance as ParticleInstance, postprocess::create_mesh as create_pp_mesh, shadow::Locals as ShadowLocals, skybox::create_mesh as create_skybox_mesh, sprite::{Instance as SpriteInstance, Locals as SpriteLocals}, - terrain::Locals as TerrainLocals, + terrain::{Locals as TerrainLocals, TerrainLayout, Vertex as TerrainVertex}, ui::{ create_quad as create_ui_quad, create_quad_vert_gradient as create_ui_quad_vert_gradient, create_tri as create_ui_tri, Locals as UiLocals, Mode as UiMode, }, - GlobalModel, Globals, Light, Shadow, + GlobalModel, Globals, GlobalsLayouts, Light, Shadow, }, renderer::{ColLightInfo, Renderer}, texture::Texture, diff --git a/voxygen/src/render/pipelines/figure.rs b/voxygen/src/render/pipelines/figure.rs index aa2612f656..f1b94969c9 100644 --- a/voxygen/src/render/pipelines/figure.rs +++ b/voxygen/src/render/pipelines/figure.rs @@ -1,5 +1,5 @@ use super::{ - super::{Mesh, Model}, + super::{AaMode, GlobalsLayouts, Mesh, Model}, terrain::Vertex, }; use crate::mesh::greedy::GreedyMesh; @@ -107,20 +107,6 @@ impl Default for BoneData { fn default() -> Self { Self::new(anim::vek::Mat4::identity(), anim::vek::Mat4::identity()) } } -pub struct FigureLayout { - pub locals: wgpu::BindGroupLayout, - pub bone_data: wgpu::BindGroupLayout, -} - -impl FigureLayout { - pub fn new(device: &wgpu::Device) -> Self { - Self { - locals: Locals::locals_layout(device), - bone_data: BoneData::bone_data_layout(device), - } - } -} - pub struct FigureModel { pub opaque: Model, /* TODO: Consider using mipmaps instead of storing multiple texture atlases for different @@ -141,48 +127,138 @@ impl FigureModel { pub type BoneMeshes = (Mesh, anim::vek::Aabb); -//gfx_defines! { -// constant Locals { -// model_mat: [[f32; 4]; 4] = "model_mat", -// highlight_col: [f32; 4] = "highlight_col", -// model_light: [f32; 4] = "model_light", -// atlas_offs: [i32; 4] = "atlas_offs", -// model_pos: [f32; 3] = "model_pos", -// flags: u32 = "flags", -// } -// -// constant BoneData { -// bone_mat: [[f32; 4]; 4] = "bone_mat", -// normals_mat: [[f32; 4]; 4] = "normals_mat", -// } -// -// pipeline pipe { -// vbuf: gfx::VertexBuffer<::Vertex> = (), -// // abuf: gfx::VertexBuffer<::Vertex> = -// (), col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light", -// -// locals: gfx::ConstantBuffer = "u_locals", -// globals: gfx::ConstantBuffer = "u_globals", -// bones: gfx::ConstantBuffer = "u_bones", -// lights: gfx::ConstantBuffer = "u_lights", -// shadows: gfx::ConstantBuffer = "u_shadows", -// -// point_shadow_maps: gfx::TextureSampler = "t_point_shadow_maps", -// directed_shadow_maps: gfx::TextureSampler = -// "t_directed_shadow_maps", -// -// alt: gfx::TextureSampler<[f32; 2]> = "t_alt", -// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", -// -// noise: gfx::TextureSampler = "t_noise", -// -// // Shadow stuff -// light_shadows: gfx::ConstantBuffer = -// "u_light_shadows", -// -// tgt_color: gfx::BlendTarget = ("tgt_color", -// ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth_stencil: -// gfx::DepthTarget = gfx::preset::depth::LESS_EQUAL_WRITE, -// // tgt_depth_stencil: gfx::DepthStencilTarget = -// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff, -// (StencilOp::Keep,StencilOp::Keep,StencilOp::Replace))), } +pub struct FigureLayout { + pub locals: wgpu::BindGroupLayout, + pub bone_data: wgpu::BindGroupLayout, + pub col_lights: wgpu::BindGroupLayout, +} + +impl FigureLayout { + pub fn new(device: &wgpu::Device) -> Self { + Self { + locals: Locals::layout(device), + bone_data: BoneData::layout(device), + col_lights: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }), + } + } +} + +pub struct FigurePipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl FigurePipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + global_layout: &GlobalsLayouts, + layout: &FigureLayout, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Figure pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[ + &global_layout.globals, + &global_layout.alt_horizon, + &global_layout.light, + &global_layout.shadow, + &global_layout.shadow_maps, + &global_layout.light_shadows, + &layout.locals, + &layout.bone_data, + &layout.col_lights, + ], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Figure pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: sc_desc.format, + color_blend: wgpu::BlendDescriptor { + src_factor: wgpu::BlendFactor::SrcAlpha, + dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, + operation: wgpu::BlendOperation::Add, + }, + alpha_blend: wgpu::BlendDescriptor { + src_factor: wgpu::BlendFactor::One, + dst_factor: wgpu::BlendFactor::One, + operation: wgpu::BlendOperation::Add, + }, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[Vertex::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } +} diff --git a/voxygen/src/render/pipelines/fluid.rs b/voxygen/src/render/pipelines/fluid.rs index e2fc1ebd03..37180d2b84 100644 --- a/voxygen/src/render/pipelines/fluid.rs +++ b/voxygen/src/render/pipelines/fluid.rs @@ -1,41 +1,7 @@ +use super::super::{AaMode, GlobalsLayouts}; use vek::*; use zerocopy::AsBytes; -// gfx_defines! { -// vertex Vertex { -// pos_norm: u32 = "v_pos_norm", -// } - -// pipeline pipe { -// vbuf: gfx::VertexBuffer = (), - -// locals: gfx::ConstantBuffer = "u_locals", -// globals: gfx::ConstantBuffer = "u_globals", -// lights: gfx::ConstantBuffer = "u_lights", -// shadows: gfx::ConstantBuffer = "u_shadows", - -// point_shadow_maps: gfx::TextureSampler = "t_point_shadow_maps", -// directed_shadow_maps: gfx::TextureSampler = -// "t_directed_shadow_maps", - -// alt: gfx::TextureSampler<[f32; 2]> = "t_alt", -// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", - -// noise: gfx::TextureSampler = "t_noise", -// waves: gfx::TextureSampler<[f32; 4]> = "t_waves", - -// // Shadow stuff -// light_shadows: gfx::ConstantBuffer = -// "u_light_shadows", - -// tgt_color: gfx::BlendTarget = ("tgt_color", -// ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth_stencil: -// gfx::DepthTarget = gfx::preset::depth::LESS_EQUAL_TEST, -// // tgt_depth_stencil: gfx::DepthStencilTarget = -// (gfx::preset::depth::LESS_EQUAL_TEST,Stencil::new(Comparison::Always,0xff, -// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), } -// } - #[repr(C)] #[derive(Copy, Clone, Debug, AsBytes)] pub struct Vertex { @@ -64,4 +30,147 @@ impl Vertex { | (norm_bits & 0x7) << 29, } } + + fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { + use std::mem; + wgpu::VertexBufferDescriptor { + stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &[wgpu::VertexAttributeDescriptor { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Uint, + }], + } + } +} + +pub struct FluidLayout { + pub waves: wgpu::BindGroupLayout, +} + +impl FluidLayout { + pub fn new(device: &wgpu::Device) -> Self { + Self { + waves: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }), + } + } +} + +pub struct FluidPipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl FluidPipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + global_layout: &GlobalsLayouts, + layout: &FluidLayout, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Fluid pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[ + &global_layout.globals, + &global_layout.alt_horizon, + &global_layout.light, + &global_layout.shadow, + &global_layout.shadow_maps, + &global_layout.light_shadows, + &layout.waves, + ], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Fluid pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::None, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: sc_desc.format, + color_blend: wgpu::BlendDescriptor { + src_factor: wgpu::BlendFactor::SrcAlpha, + dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, + operation: wgpu::BlendOperation::Add, + }, + alpha_blend: wgpu::BlendDescriptor { + src_factor: wgpu::BlendFactor::One, + dst_factor: wgpu::BlendFactor::One, + operation: wgpu::BlendOperation::Add, + }, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: false, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[Vertex::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } } diff --git a/voxygen/src/render/pipelines/lod_terrain.rs b/voxygen/src/render/pipelines/lod_terrain.rs index bc3c22dc6b..4dd721c56e 100644 --- a/voxygen/src/render/pipelines/lod_terrain.rs +++ b/voxygen/src/render/pipelines/lod_terrain.rs @@ -1,35 +1,7 @@ -use super::super::{Renderer, Texture}; +use super::super::{AaMode, GlobalsLayouts, Renderer, Texture}; use vek::*; use zerocopy::AsBytes; -// gfx_defines! { -// vertex Vertex { -// pos: [f32; 2] = "v_pos", -// } - -// constant Locals { -// nul: [f32; 4] = "nul", -// } - -// pipeline pipe { -// vbuf: gfx::VertexBuffer = (), - -// locals: gfx::ConstantBuffer = "u_locals", -// globals: gfx::ConstantBuffer = "u_globals", -// map: gfx::TextureSampler<[f32; 4]> = "t_map", -// alt: gfx::TextureSampler<[f32; 2]> = "t_alt", -// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", - -// noise: gfx::TextureSampler = "t_noise", - -// tgt_color: gfx::RenderTarget = "tgt_color", -// tgt_depth_stencil: gfx::DepthTarget = -// gfx::preset::depth::LESS_EQUAL_WRITE, // tgt_depth_stencil: -// gfx::DepthStencilTarget = -// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff, -// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), } -// } - #[repr(C)] #[derive(Copy, Clone, Debug, AsBytes)] pub struct Vertex { @@ -42,6 +14,19 @@ impl Vertex { pos: pos.into_array(), } } + + fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { + use std::mem; + wgpu::VertexBufferDescriptor { + stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &[wgpu::VertexAttributeDescriptor { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float2, + }], + } + } } pub struct LodData { @@ -156,3 +141,88 @@ impl LodData { // } } } + +pub struct LodTerrainPipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl LodTerrainPipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + global_layout: &GlobalsLayouts, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Lod terrain pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[ + &global_layout.globals, + &global_layout.alt_horizon, + &global_layout.lod_map, + ], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Lod terrain pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: sc_desc.format, + color_blend: wgpu::BlendDescriptor::REPLACE, + alpha_blend: wgpu::BlendDescriptor::REPLACE, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[Vertex::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } +} diff --git a/voxygen/src/render/pipelines/mod.rs b/voxygen/src/render/pipelines/mod.rs index 8a496d23c9..39cfeb3768 100644 --- a/voxygen/src/render/pipelines/mod.rs +++ b/voxygen/src/render/pipelines/mod.rs @@ -225,34 +225,201 @@ pub struct GlobalModel { pub shadow_mats: Consts, } -//gfx_defines! { -// constant Globals { -// view_mat: [[f32; 4]; 4] = "view_mat", -// proj_mat: [[f32; 4]; 4] = "proj_mat", -// all_mat: [[f32; 4]; 4] = "all_mat", -// cam_pos: [f32; 4] = "cam_pos", -// focus_off: [f32; 4] = "focus_off", -// focus_pos: [f32; 4] = "focus_pos", -// /// NOTE: view_distance.x is the horizontal view distance, -// view_distance.y is the LOD /// detail, view_distance.z is the -// /// minimum height over any land chunk (i.e. the sea level), and -// view_distance.w is the /// maximum height over this minimum height. -// /// -// /// TODO: Fix whatever alignment issue requires these uniforms to be -// aligned. view_distance: [f32; 4] = "view_distance", -// time_of_day: [f32; 4] = "time_of_day", // TODO: Make this f64. -// sun_dir: [f32; 4] = "sun_dir", -// moon_dir: [f32; 4] = "moon_dir", -// tick: [f32; 4] = "tick", -// /// x, y represent the resolution of the screen; -// /// w, z represent the near and far planes of the shadow map. -// screen_res: [f32; 4] = "screen_res", -// light_shadow_count: [u32; 4] = "light_shadow_count", -// shadow_proj_factors: [f32; 4] = "shadow_proj_factors", -// medium: [u32; 4] = "medium", -// select_pos: [i32; 4] = "select_pos", -// gamma_exposure: [f32; 4] = "gamma_exposure", -// ambiance: f32 = "ambiance", -// cam_mode: u32 = "cam_mode", -// sprite_render_distance: f32 = "sprite_render_distance", -// } +pub struct GlobalsLayouts { + pub globals: wgpu::BindGroupLayout, + pub light: wgpu::BindGroupLayout, + pub shadow: wgpu::BindGroupLayout, + pub alt_horizon: wgpu::BindGroupLayout, + pub shadow_maps: wgpu::BindGroupLayout, + pub light_shadows: wgpu::BindGroupLayout, + pub lod_map: wgpu::BindGroupLayout, +} + +impl GlobalsLayouts { + pub fn new(device: &wgpu::Device) -> Self { + let globals = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("Globals layout"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: None, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + dimension: wgpu::TextureViewDimension::D2, + component_type: wgpu::TextureComponentType::Float, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 2, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }); + let light = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("Light layout"), + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: None, + }, + count: None, + }], + }); + let shadow = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("Shadow layout"), + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: None, + }, + count: None, + }], + }); + + let alt_horizon = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("alt/horizon layout"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 2, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 3, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }); + + let shadow_maps = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("Shadow maps layout"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }); + + let light_shadows = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("Light shadows layout"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 2, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 3, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }); + + let lod_map = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("Lod layout"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }); + + Self { + globals, + light, + shadow, + alt_horizon, + shadow_maps, + light_shadows, + lod_map, + } + } +} diff --git a/voxygen/src/render/pipelines/particle.rs b/voxygen/src/render/pipelines/particle.rs index ff5dd8cada..61afce0a53 100644 --- a/voxygen/src/render/pipelines/particle.rs +++ b/voxygen/src/render/pipelines/particle.rs @@ -1,77 +1,7 @@ +use super::super::{AaMode, GlobalsLayouts}; use vek::*; use zerocopy::AsBytes; -// gfx_defines! { -// vertex Vertex { -// pos: [f32; 3] = "v_pos", -// // ____BBBBBBBBGGGGGGGGRRRRRRRR -// // col: u32 = "v_col", -// // ...AANNN -// // A = AO -// // N = Normal -// norm_ao: u32 = "v_norm_ao", -// } -// -// vertex Instance { -// // created_at time, so we can calculate time relativity, needed for -// relative animation. // can save 32 bits per instance, for particles -// that are not relatively animated. inst_time: f32 = "inst_time", -// -// // The lifespan in seconds of the particle -// inst_lifespan: f32 = "inst_lifespan", -// -// // a seed value for randomness -// // can save 32 bits per instance, for particles that don't need -// randomness/uniqueness. inst_entropy: f32 = "inst_entropy", -// -// // modes should probably be seperate shaders, as a part of scaling -// and optimisation efforts. // can save 32 bits per instance, and have -// cleaner tailor made code. inst_mode: i32 = "inst_mode", -// -// // A direction for particles to move in -// inst_dir: [f32; 3] = "inst_dir", -// -// // a triangle is: f32 x 3 x 3 x 1 = 288 bits -// // a quad is: f32 x 3 x 3 x 2 = 576 bits -// // a cube is: f32 x 3 x 3 x 12 = 3456 bits -// // this vec is: f32 x 3 x 1 x 1 = 96 bits (per instance!) -// // consider using a throw-away mesh and -// // positioning the vertex vertices instead, -// // if we have: -// // - a triangle mesh, and 3 or more instances. -// // - a quad mesh, and 6 or more instances. -// // - a cube mesh, and 36 or more instances. -// inst_pos: [f32; 3] = "inst_pos", -// } -// -// pipeline pipe { -// vbuf: gfx::VertexBuffer = (), -// ibuf: gfx::InstanceBuffer = (), -// -// globals: gfx::ConstantBuffer = "u_globals", -// lights: gfx::ConstantBuffer = "u_lights", -// shadows: gfx::ConstantBuffer = "u_shadows", -// -// point_shadow_maps: gfx::TextureSampler = "t_point_shadow_maps", -// directed_shadow_maps: gfx::TextureSampler = -// "t_directed_shadow_maps", -// -// alt: gfx::TextureSampler<[f32; 2]> = "t_alt", -// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", -// -// noise: gfx::TextureSampler = "t_noise", -// -// // Shadow stuff -// light_shadows: gfx::ConstantBuffer = -// "u_light_shadows", -// -// tgt_color: gfx::BlendTarget = ("tgt_color", -// ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth_stencil: -// gfx::DepthTarget = gfx::preset::depth::LESS_EQUAL_WRITE, -// // tgt_depth_stencil: gfx::DepthStencilTarget = -// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff, -// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), } - #[repr(C)] #[derive(Copy, Clone, Debug, AsBytes)] pub struct Vertex { @@ -100,6 +30,15 @@ impl Vertex { norm_ao: norm_bits, } } + + fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { + use std::mem; + wgpu::VertexBufferDescriptor { + stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &wgpu::vertex_attr_array![0 => Float3, 1 => Uint], + } + } } #[derive(Copy, Clone)] @@ -205,8 +144,113 @@ impl Instance { inst_dir: (inst_pos2 - inst_pos).into_array(), } } + + fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { + use std::mem; + wgpu::VertexBufferDescriptor { + stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Instance, + attributes: &wgpu::vertex_attr_array![0 => Float, 1 => Float, 2 => Float, 3 => Int, 4 => Float3], + } + } } impl Default for Instance { fn default() -> Self { Self::new(0.0, 0.0, ParticleMode::CampfireSmoke, Vec3::zero()) } } + +pub struct ParticlePipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl ParticlePipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + global_layout: &GlobalsLayouts, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Particle pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[ + &global_layout.globals, + &global_layout.alt_horizon, + &global_layout.light, + &global_layout.shadow, + &global_layout.shadow_maps, + &global_layout.light_shadows, + ], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Particle pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: sc_desc.format, + color_blend: wgpu::BlendDescriptor { + src_factor: wgpu::BlendFactor::SrcAlpha, + dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, + operation: wgpu::BlendOperation::Add, + }, + alpha_blend: wgpu::BlendDescriptor { + src_factor: wgpu::BlendFactor::One, + dst_factor: wgpu::BlendFactor::One, + operation: wgpu::BlendOperation::Add, + }, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[Vertex::desc(), Instance::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } +} diff --git a/voxygen/src/render/pipelines/postprocess.rs b/voxygen/src/render/pipelines/postprocess.rs index 14889c9292..4dd9df9474 100644 --- a/voxygen/src/render/pipelines/postprocess.rs +++ b/voxygen/src/render/pipelines/postprocess.rs @@ -1,38 +1,7 @@ -use super::super::{Mesh, Tri}; +use super::super::{AaMode, GlobalsLayouts, Mesh, Tri}; use vek::*; use zerocopy::AsBytes; -// gfx_defines! { -// vertex Vertex { -// pos: [f32; 2] = "v_pos", -// } -// -// constant Locals { -// proj_mat_inv: [[f32; 4]; 4] = "proj_mat_inv", -// view_mat_inv: [[f32; 4]; 4] = "view_mat_inv", -// } -// -// pipeline pipe { -// vbuf: gfx::VertexBuffer = (), -// -// locals: gfx::ConstantBuffer = "u_locals", -// globals: gfx::ConstantBuffer = "u_globals", -// -// map: gfx::TextureSampler<[f32; 4]> = "t_map", -// alt: gfx::TextureSampler<[f32; 2]> = "t_alt", -// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", -// -// color_sampler: gfx::TextureSampler<::View> = "src_color", depth_sampler: -// gfx::TextureSampler<::View> = -// "src_depth", -// -// noise: gfx::TextureSampler = "t_noise", -// -// tgt_color: gfx::RenderTarget = "tgt_color", -// } -// } - #[repr(C)] #[derive(Copy, Clone, Debug, AsBytes)] pub struct Locals { @@ -59,6 +28,21 @@ pub struct Vertex { pub pos: [f32; 2], } +impl Vertex { + fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { + use std::mem; + wgpu::VertexBufferDescriptor { + stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &[wgpu::VertexAttributeDescriptor { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float2, + }], + } + } +} + pub fn create_mesh() -> Mesh { let mut mesh = Mesh::new(); @@ -78,3 +62,117 @@ pub fn create_mesh() -> Mesh { mesh } + +pub struct PostProcessLayout { + pub src_color: wgpu::BindGroupLayout, +} + +impl PostProcessLayout { + pub fn new(device: &wgpu::Device) -> Self { + Self { + src_color: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }), + } + } +} + +pub struct PostProcessPipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl PostProcessPipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + global_layout: &GlobalsLayouts, + layout: &PostProcessLayout, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Post process pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[&global_layout.globals, &layout.src_color], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Post process pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: sc_desc.format, + color_blend: wgpu::BlendDescriptor::REPLACE, + alpha_blend: wgpu::BlendDescriptor::REPLACE, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: false, + depth_compare: wgpu::CompareFunction::Always, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[Vertex::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } +} diff --git a/voxygen/src/render/pipelines/shadow.rs b/voxygen/src/render/pipelines/shadow.rs index 4d9587cb58..411b448d8f 100644 --- a/voxygen/src/render/pipelines/shadow.rs +++ b/voxygen/src/render/pipelines/shadow.rs @@ -1,47 +1,9 @@ -use super::super::{ColLightInfo, Renderer, Texture}; +use super::super::{ + AaMode, ColLightInfo, FigureLayout, GlobalsLayouts, Renderer, TerrainVertex, Texture, +}; use vek::*; use zerocopy::AsBytes; -// gfx_defines! { -// constant Locals { -// shadow_matrices: [[f32; 4]; 4] = "shadowMatrices", -// texture_mats: [[f32; 4]; 4] = "texture_mat", -// } - -// pipeline pipe { -// // Terrain vertex stuff -// vbuf: gfx::VertexBuffer = (), - -// locals: gfx::ConstantBuffer = "u_locals", -// globals: gfx::ConstantBuffer = "u_globals", - -// // Shadow stuff -// light_shadows: gfx::ConstantBuffer = "u_light_shadows", - -// tgt_depth_stencil: gfx::DepthTarget = -// gfx::state::Depth { fun: gfx::state::Comparison::Less, -// write: true, -// }, -// } - -// pipeline figure_pipe { -// // Terrain vertex stuff -// vbuf: gfx::VertexBuffer = (), - -// locals: gfx::ConstantBuffer = "u_locals", -// bones: gfx::ConstantBuffer = "u_bones", -// globals: gfx::ConstantBuffer = "u_globals", - -// // Shadow stuff -// light_shadows: gfx::ConstantBuffer = "u_light_shadows", - -// tgt_depth_stencil: gfx::DepthTarget = -// gfx::state::Depth { fun: gfx::state::Comparison::Less, -// write: true, -// }, -// } -// } - #[repr(C)] #[derive(Copy, Clone, Debug, AsBytes)] pub struct Locals { @@ -58,6 +20,33 @@ impl Locals { } pub fn default() -> Self { Self::new(Mat4::identity(), Mat4::identity()) } + + fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout { + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: None, + }, + count: None, + }], + }) + } +} + +pub struct ShadowLayout { + pub locals: wgpu::BindGroupLayout, +} + +impl ShadowLayout { + pub fn new(device: &wgpu::Device) -> Self { + Self { + locals: Locals::layout(device), + } + } } pub fn create_col_lights( @@ -98,3 +87,165 @@ pub fn create_col_lights( col_lights.as_bytes(), ) } + +pub struct ShadowFigurePipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl ShadowFigurePipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + global_layout: &GlobalsLayouts, + layout: &FigureLayout, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Shadow figure pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[ + &global_layout.globals, + &global_layout.light_shadows, + &layout.waves, + ], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Shadow figure pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::Less, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[TerrainVertex::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } +} + +pub struct ShadowPipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl ShadowPipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + global_layout: &GlobalsLayouts, + layout: &ShadowLayout, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Shadow pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[ + &global_layout.globals, + &global_layout.light_shadows, + &layout.locals, + ], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Shadow pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::Less, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[TerrainVertex::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } +} diff --git a/voxygen/src/render/pipelines/skybox.rs b/voxygen/src/render/pipelines/skybox.rs index 7ece139435..a3c4ce42a0 100644 --- a/voxygen/src/render/pipelines/skybox.rs +++ b/voxygen/src/render/pipelines/skybox.rs @@ -1,40 +1,108 @@ -use super::super::{Mesh, Quad}; +use super::super::{AaMode, GlobalsLayouts, Mesh, Quad}; use zerocopy::AsBytes; -// gfx_defines! { -// vertex Vertex { -// pos: [f32; 3] = "v_pos", -// } - -// constant Locals { -// nul: [f32; 4] = "nul", -// } - -// pipeline pipe { -// vbuf: gfx::VertexBuffer = (), - -// locals: gfx::ConstantBuffer = "u_locals", -// globals: gfx::ConstantBuffer = "u_globals", - -// alt: gfx::TextureSampler<[f32; 2]> = "t_alt", -// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", - -// noise: gfx::TextureSampler = "t_noise", - -// tgt_color: gfx::RenderTarget = "tgt_color", -// tgt_depth_stencil: gfx::DepthTarget = -// gfx::preset::depth::LESS_EQUAL_TEST, // tgt_depth_stencil: -// gfx::DepthStencilTarget = -// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff, -// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), } -// } - #[repr(C)] #[derive(Copy, Clone, Debug, AsBytes)] pub struct Vertex { pub pos: [f32; 3], } +impl Vertex { + fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { + use std::mem; + wgpu::VertexBufferDescriptor { + stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &[wgpu::VertexAttributeDescriptor { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float3, + }], + } + } +} + +pub struct SkyboxPipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl SkyboxPipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + layouts: &GlobalsLayouts, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Skybox pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[&layouts.globals, &layouts.alt_horizon], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Skybox pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: sc_desc.format, + color_blend: wgpu::BlendDescriptor::REPLACE, + alpha_blend: wgpu::BlendDescriptor::REPLACE, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[Vertex::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } +} + pub fn create_mesh() -> Mesh { let mut mesh = Mesh::new(); diff --git a/voxygen/src/render/pipelines/sprite.rs b/voxygen/src/render/pipelines/sprite.rs index c5c413bc3c..2fdd08e4df 100644 --- a/voxygen/src/render/pipelines/sprite.rs +++ b/voxygen/src/render/pipelines/sprite.rs @@ -1,73 +1,8 @@ +use super::super::{AaMode, GlobalsLayouts, TerrainLayout}; use core::fmt; use vek::*; use zerocopy::AsBytes; -// gfx_defines! { -// vertex Vertex { -// pos: [f32; 3] = "v_pos", -// // Because we try to restrict terrain sprite data to a 128×128 block -// // we need an offset into the texture atlas. -// atlas_pos: u32 = "v_atlas_pos", -// // ____BBBBBBBBGGGGGGGGRRRRRRRR -// // col: u32 = "v_col", -// // ...AANNN -// // A = AO -// // N = Normal -// norm_ao: u32 = "v_norm_ao", -// } -// -// constant Locals { -// // Each matrix performs rotatation, translation, and scaling, -// relative to the sprite // origin, for all sprite instances. The -// matrix will be in an array indexed by the // sprite instance's -// orientation (0 through 7). mat: [[f32; 4]; 4] = "mat", -// wind_sway: [f32; 4] = "wind_sway", -// offs: [f32; 4] = "offs", -// } -// -// vertex/*constant*/ Instance { -// // Terrain block position and orientation -// pos_ori: u32 = "inst_pos_ori", -// inst_mat0: [f32; 4] = "inst_mat0", -// inst_mat1: [f32; 4] = "inst_mat1", -// inst_mat2: [f32; 4] = "inst_mat2", -// inst_mat3: [f32; 4] = "inst_mat3", -// inst_light: [f32; 4] = "inst_light", -// inst_wind_sway: f32 = "inst_wind_sway", -// } -// -// pipeline pipe { -// vbuf: gfx::VertexBuffer = (), -// ibuf: gfx::InstanceBuffer = (), -// col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light", -// -// locals: gfx::ConstantBuffer = "u_locals", -// // A sprite instance is a cross between a sprite and a terrain chunk. -// terrain_locals: gfx::ConstantBuffer = -// "u_terrain_locals", globals: gfx::ConstantBuffer = -// "u_globals", lights: gfx::ConstantBuffer = "u_lights", -// shadows: gfx::ConstantBuffer = "u_shadows", -// -// point_shadow_maps: gfx::TextureSampler = "t_point_shadow_maps", -// directed_shadow_maps: gfx::TextureSampler = -// "t_directed_shadow_maps", -// -// alt: gfx::TextureSampler<[f32; 2]> = "t_alt", -// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", -// -// noise: gfx::TextureSampler = "t_noise", -// -// // Shadow stuff -// light_shadows: gfx::ConstantBuffer = -// "u_light_shadows", -// -// tgt_color: gfx::BlendTarget = ("tgt_color", -// ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth_stencil: -// gfx::DepthTarget = gfx::preset::depth::LESS_EQUAL_WRITE, -// // tgt_depth_stencil: gfx::DepthStencilTarget = -// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff, -// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), } - #[repr(C)] #[derive(Copy, Clone, Debug, AsBytes)] pub struct Vertex { @@ -123,6 +58,15 @@ impl Vertex { norm_ao: norm_bits, } } + + fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { + use std::mem; + wgpu::VertexBufferDescriptor { + stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &wgpu::vertex_attr_array![0 => Float3, 1 => Uint, 2 => Uint], + } + } } #[repr(C)] @@ -162,6 +106,15 @@ impl Instance { inst_wind_sway: wind_sway, } } + + fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { + use std::mem; + wgpu::VertexBufferDescriptor { + stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Instance, + attributes: &wgpu::vertex_attr_array![0 => Uint, 1 => Float4,2 => Float4, 3 => Float4,4 => Float4,5 => Float], + } + } } impl Default for Instance { @@ -191,4 +144,154 @@ impl Locals { offs: [offs.x, offs.y, offs.z, 0.0], } } + + fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout { + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: None, + }, + count: None, + }], + }) + } +} + +pub struct SpriteLayout { + pub locals: wgpu::BindGroupLayout, + pub col_lights: wgpu::BindGroupLayout, +} + +impl SpriteLayout { + pub fn new(device: &wgpu::Device) -> Self { + Self { + locals: Locals::layout(device), + col_lights: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }), + } + } +} + +pub struct SpritePipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl SpritePipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + global_layout: &GlobalsLayouts, + layout: &SpriteLayout, + terrain_layout: &TerrainLayout, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Sprite pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[ + &global_layout.globals, + &global_layout.alt_horizon, + &global_layout.light, + &global_layout.shadow, + &global_layout.shadow_maps, + &global_layout.light_shadows, + &layout.col_lights, + &layout.locals, + &terrain_layout.locals, + ], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Sprite pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: sc_desc.format, + color_blend: wgpu::BlendDescriptor { + src_factor: wgpu::BlendFactor::SrcAlpha, + dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, + operation: wgpu::BlendOperation::Add, + }, + alpha_blend: wgpu::BlendDescriptor { + src_factor: wgpu::BlendFactor::One, + dst_factor: wgpu::BlendFactor::One, + operation: wgpu::BlendOperation::Add, + }, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[Vertex::desc(), Instance::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } } diff --git a/voxygen/src/render/pipelines/terrain.rs b/voxygen/src/render/pipelines/terrain.rs index e38b6db488..8694b59e26 100644 --- a/voxygen/src/render/pipelines/terrain.rs +++ b/voxygen/src/render/pipelines/terrain.rs @@ -1,48 +1,7 @@ +use super::super::{AaMode, GlobalsLayouts}; use vek::*; use zerocopy::AsBytes; -// gfx_defines! { -// vertex Vertex { -// pos_norm: u32 = "v_pos_norm", -// atlas_pos: u32 = "v_atlas_pos", -// } - -// constant Locals { -// model_offs: [f32; 3] = "model_offs", -// load_time: f32 = "load_time", -// atlas_offs: [i32; 4] = "atlas_offs", -// } - -// pipeline pipe { -// vbuf: gfx::VertexBuffer = (), -// col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light", - -// locals: gfx::ConstantBuffer = "u_locals", -// globals: gfx::ConstantBuffer = "u_globals", -// lights: gfx::ConstantBuffer = "u_lights", -// shadows: gfx::ConstantBuffer = "u_shadows", - -// point_shadow_maps: gfx::TextureSampler = "t_point_shadow_maps", -// directed_shadow_maps: gfx::TextureSampler = -// "t_directed_shadow_maps", - -// alt: gfx::TextureSampler<[f32; 2]> = "t_alt", -// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", - -// noise: gfx::TextureSampler = "t_noise", - -// // Shadow stuff -// light_shadows: gfx::ConstantBuffer = -// "u_light_shadows", - -// tgt_color: gfx::RenderTarget = "tgt_color", -// tgt_depth_stencil: gfx::DepthTarget = -// gfx::preset::depth::LESS_EQUAL_WRITE, // tgt_depth_stencil: -// gfx::DepthStencilTarget = -// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff, -// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), } -// } - #[repr(C)] #[derive(Copy, Clone, Debug, AsBytes)] pub struct Vertex { @@ -158,6 +117,15 @@ impl Vertex { pub fn set_bone_idx(&mut self, bone_idx: u8) { self.pos_norm = (self.pos_norm & !(0xF << 27)) | ((bone_idx as u32 & 0xF) << 27); } + + fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { + use std::mem; + wgpu::VertexBufferDescriptor { + stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &wgpu::vertex_attr_array![0 => Uint,1 => Uint], + } + } } #[repr(C)] @@ -176,4 +144,144 @@ impl Locals { atlas_offs: [0; 4], } } + + fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout { + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: None, + }, + count: None, + }], + }) + } +} + +pub struct TerrainLayout { + pub locals: wgpu::BindGroupLayout, + pub col_lights: wgpu::BindGroupLayout, +} + +impl TerrainLayout { + pub fn new(device: &wgpu::Device) -> Self { + Self { + locals: Locals::layout(device), + col_lights: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }), + } + } +} + +pub struct TerrainPipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl TerrainPipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + global_layout: &GlobalsLayouts, + layout: &TerrainLayout, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Terrain pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[ + &global_layout.globals, + &global_layout.alt_horizon, + &global_layout.light, + &global_layout.shadow, + &global_layout.shadow_maps, + &global_layout.light_shadows, + &layout.locals, + &layout.col_lights, + ], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Terrain pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: sc_desc.format, + color_blend: wgpu::BlendDescriptor::REPLACE, + alpha_blend: wgpu::BlendDescriptor::REPLACE, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[Vertex::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } } diff --git a/voxygen/src/render/pipelines/ui.rs b/voxygen/src/render/pipelines/ui.rs index 8685d99896..57e475a609 100644 --- a/voxygen/src/render/pipelines/ui.rs +++ b/voxygen/src/render/pipelines/ui.rs @@ -1,34 +1,7 @@ -use super::super::{Quad, Tri}; +use super::super::{AaMode, GlobalsLayouts, Quad, Tri}; use vek::*; use zerocopy::AsBytes; -// gfx_defines! { -// vertex Vertex { -// pos: [f32; 2] = "v_pos", -// uv: [f32; 2] = "v_uv", -// color: [f32; 4] = "v_color", -// center: [f32; 2] = "v_center", -// mode: u32 = "v_mode", -// } - -// constant Locals { -// pos: [f32; 4] = "w_pos", -// } - -// pipeline pipe { -// vbuf: gfx::VertexBuffer = (), - -// locals: gfx::ConstantBuffer = "u_locals", -// globals: gfx::ConstantBuffer = "u_globals", -// tex: gfx::TextureSampler<[f32; 4]> = "u_tex", - -// scissor: gfx::Scissor = (), - -// tgt_color: gfx::BlendTarget = ("tgt_color", -// gfx::state::ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth: -// gfx::DepthTarget = gfx::preset::depth::LESS_EQUAL_TEST, } -// } - #[repr(C)] #[derive(Copy, Clone, Debug, AsBytes)] pub struct Vertex { @@ -39,12 +12,40 @@ pub struct Vertex { mode: u32, } +impl Vertex { + fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { + use std::mem; + wgpu::VertexBufferDescriptor { + stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &wgpu::vertex_attr_array![0 => Float2, 1 => Float2, 2 => Float4, 3 => Float2, 4 => Uint], + } + } +} + #[repr(C)] #[derive(Copy, Clone, Debug, AsBytes)] pub struct Locals { pos: [f32; 4], } +impl Locals { + fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout { + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: None, + }, + count: None, + }], + }) + } +} + impl From> for Locals { fn from(pos: Vec4) -> Self { Self { @@ -94,6 +95,130 @@ impl Mode { } } +pub struct UILayout { + pub locals: wgpu::BindGroupLayout, + pub tex: wgpu::BindGroupLayout, +} + +impl UILayout { + pub fn new(device: &wgpu::Device) -> Self { + Self { + locals: Locals::layout(device), + tex: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + component_type: wgpu::TextureComponentType::Float, + dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { comparison: false }, + count: None, + }, + ], + }), + } + } +} + +pub struct UIPipeline { + pub pipeline: wgpu::RenderPipeline, +} + +impl UIPipeline { + pub fn new( + device: &wgpu::Device, + vs_module: &wgpu::ShaderModule, + fs_module: &wgpu::ShaderModule, + sc_desc: &wgpu::SwapChainDescriptor, + global_layout: &GlobalsLayouts, + layout: &UILayout, + aa_mode: AaMode, + ) -> Self { + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("UI pipeline layout"), + push_constant_ranges: &[], + bind_group_layouts: &[&global_layout.globals, &layout.locals, &layout.tex], + }); + + let samples = match aa_mode { + AaMode::None | AaMode::Fxaa => 1, + // TODO: Ensure sampling in the shader is exactly between the 4 texels + AaMode::SsaaX4 => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("UI pipeline"), + layout: Some(&render_pipeline_layout), + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + clamp_depth: false, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: sc_desc.format, + color_blend: wgpu::BlendDescriptor { + src_factor: wgpu::BlendFactor::SrcAlpha, + dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, + operation: wgpu::BlendOperation::Add, + }, + alpha_blend: wgpu::BlendDescriptor { + src_factor: wgpu::BlendFactor::One, + dst_factor: wgpu::BlendFactor::One, + operation: wgpu::BlendOperation::Add, + }, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth24Plus, + depth_write_enabled: false, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilStateDescriptor { + front: wgpu::StencilStateFaceDescriptor::IGNORE, + back: wgpu::StencilStateFaceDescriptor::IGNORE, + read_mask: !0, + write_mask: !0, + }, + }), + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[Vertex::desc()], + }, + sample_count: samples, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + Self { + pipeline: render_pipeline, + } + } +} + pub fn create_quad( rect: Aabr, uv_rect: Aabr, diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index 4a6fed8373..c332589e9f 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -5,7 +5,7 @@ use super::{ model::Model, pipelines::{ clouds, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain, - ui, GlobalModel, Globals, + ui, GlobalsLayouts, }, texture::Texture, AaMode, AddressMode, CloudMode, FilterMode, FluidMode, LightingMode, RenderError, RenderMode, @@ -14,76 +14,9 @@ use super::{ use common::assets::{self, AssetExt, AssetHandle}; use common_base::span; use core::convert::TryFrom; -use glsl_include::Context as IncludeContext; use tracing::{error, info, warn}; use vek::*; -// /// Represents the format of the pre-processed color target. -// // TODO: `(gfx::format::R11_G11_B10, gfx::format::Float)` would be better in -// // theory, but it doesn't seem to work -// pub type TgtColorFmt = gfx::format::Rgba16F; -// /// Represents the format of the pre-processed depth and stencil target. -// pub type TgtDepthStencilFmt = gfx::format::Depth; -// -// /// Represents the format of the window's color target. -// pub type WinColorFmt = gfx::format::Srgba8; -// /// Represents the format of the window's depth target. -// pub type WinDepthFmt = gfx::format::Depth; -// -// /// Represents the format of the pre-processed shadow depth target. -// pub type ShadowDepthStencilFmt = gfx::format::Depth; -// -// /// A handle to a pre-processed color target. -// pub type TgtColorView = gfx::handle::RenderTargetView; /// A handle to a pre-processed depth target. -// pub type TgtDepthStencilView = -// gfx::handle::DepthStencilView; -// -// /// A handle to a window color target. -// pub type WinColorView = gfx::handle::RenderTargetView; /// A handle to a window depth target. -// pub type WinDepthView = gfx::handle::DepthStencilView; -// -// /// Represents the format of LOD shadows. -// pub type LodTextureFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm); -// -// /// Represents the format of LOD altitudes. -// pub type LodAltFmt = (gfx::format::R16_G16, gfx::format::Unorm); -// -// /// Represents the format of LOD map colors. -// pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb); -// -// /// Represents the format of greedy meshed color-light textures. -// pub type ColLightFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm); -// -// /// A handle to a shadow depth target. -// pub type ShadowDepthStencilView = -// gfx::handle::DepthStencilView; /// A handle to a shadow depth target as a resource. -// pub type ShadowResourceView = gfx::handle::ShaderResourceView< -// gfx_backend::Resources, -// ::View, -// >; -// -// /// A handle to a render color target as a resource. -// pub type TgtColorRes = gfx::handle::ShaderResourceView< -// gfx_backend::Resources, -// ::View, -// >; -// -// /// A handle to a render depth target as a resource. -// pub type TgtDepthRes = gfx::handle::ShaderResourceView< -// gfx_backend::Resources, -// ::View, -// >; -// -// /// A handle to a greedy meshed color-light texture as a resource. -// pub type ColLightRes = gfx::handle::ShaderResourceView< -// gfx_backend::Resources, -// ::View, -// >; /// A type representing data that can be converted to an immutable texture map /// of ColLight data (used for texture atlases created during greedy meshing). pub type ColLightInfo = (Vec<[u8; 4]>, Vec2); @@ -223,9 +156,23 @@ pub struct ShadowMapRenderer { point_depth_stencil_view: wgpu::TextureView, point_sampler: wgpu::Sampler, - point_pipeline: wgpu::RenderPipeline, - terrain_directed_pipeline: wgpu::RenderPipeline, - figure_directed_pipeline: wgpu::RenderPipeline, + point_pipeline: shadow::ShadowPipeline, + terrain_directed_pipeline: shadow::ShadowPipeline, + figure_directed_pipeline: shadow::ShadowFigurePipeline, + layout: shadow::ShadowLayout, +} + +/// A type that stores all the layouts associated with this renderer. +pub struct Layouts { + pub(self) global: GlobalsLayouts, + + pub(self) figure: figure::FigureLayout, + pub(self) fluid: fluid::FluidLayout, + pub(self) postprocess: postprocess::PostProcessLayout, + pub(self) shadow: shadow::ShadowLayout, + pub(self) sprite: sprite::SpriteLayout, + pub(self) terrain: terrain::TerrainLayout, + pub(self) ui: ui::UILayout, } /// A type that encapsulates rendering state. `Renderer` is central to Voxygen's @@ -249,18 +196,20 @@ pub struct Renderer { shadow_map: Option, - skybox_pipeline: wgpu::RenderPipeline, - figure_pipeline: wgpu::RenderPipeline, - terrain_pipeline: wgpu::RenderPipeline, - fluid_pipeline: wgpu::RenderPipeline, - sprite_pipeline: wgpu::RenderPipeline, - particle_pipeline: wgpu::RenderPipeline, - ui_pipeline: wgpu::RenderPipeline, - lod_terrain_pipeline: wgpu::RenderPipeline, - clouds_pipeline: wgpu::RenderPipeline, - postprocess_pipeline: wgpu::RenderPipeline, - #[allow(dead_code)] //TODO: remove ? - player_shadow_pipeline: wgpu::RenderPipeline, + layouts: Layouts, + + figure_pipeline: figure::FigurePipeline, + fluid_pipeline: fluid::FluidPipeline, + lod_terrain_pipeline: lod_terrain::LodTerrainPipeline, + particle_pipeline: particle::ParticlePipeline, + //clouds_pipeline: wgpu::RenderPipeline, + postprocess_pipeline: postprocess::PostProcessPipeline, + // Consider reenabling at some time + // player_shadow_pipeline: figure::FigurePipeline, + skybox_pipeline: skybox::SkyboxPipeline, + sprite_pipeline: sprite::SpritePipeline, + terrain_pipeline: terrain::TerrainPipeline, + ui_pipeline: ui::UIPipeline, shaders: AssetHandle, @@ -346,6 +295,30 @@ impl Renderer { let shaders = Shaders::load_expect(""); + let layouts = { + let global = GlobalsLayouts::new(&device); + + let figure = figure::FigureLayout::new(&device); + let fluid = fluid::FluidLayout::new(&device); + let postprocess = postprocess::PostProcessLayout::new(&device); + let shadow = shadow::ShadowLayout::new(&device); + let sprite = sprite::SpriteLayout::new(&device); + let terrain = terrain::TerrainLayout::new(&device); + let ui = ui::UILayout::new(&device); + + Layouts { + global, + + figure, + fluid, + postprocess, + shadow, + sprite, + terrain, + ui, + } + }; + let ( skybox_pipeline, figure_pipeline, @@ -357,13 +330,13 @@ impl Renderer { lod_terrain_pipeline, clouds_pipeline, postprocess_pipeline, - player_shadow_pipeline, + //player_shadow_pipeline, point_shadow_pipeline, terrain_directed_shadow_pipeline, figure_directed_shadow_pipeline, ) = create_pipelines( &device, - &mode, + &layouts & mode, shadow_views.is_some(), )?; @@ -389,6 +362,9 @@ impl Renderer { directed_res, directed_sampler, ) = shadow_views; + + let layout = shadow::ShadowLayout::new(&device); + Some(ShadowMapRenderer { directed_depth_stencil_view, directed_sampler, @@ -401,6 +377,8 @@ impl Renderer { point_pipeline, terrain_directed_pipeline, figure_directed_pipeline, + + layout, }) } else { None @@ -442,6 +420,8 @@ impl Renderer { shadow_map, + layouts, + skybox_pipeline, figure_pipeline, terrain_pipeline, @@ -452,9 +432,9 @@ impl Renderer { lod_terrain_pipeline, clouds_pipeline, postprocess_pipeline, - player_shadow_pipeline, - shaders, + //player_shadow_pipeline, + shader_reload_indicator, noise_tex, @@ -868,32 +848,32 @@ impl Renderer { self.encoder.clear_depth(&self.win_depth_view, 1.0); } - /// Set up shadow rendering. - pub fn start_shadows(&mut self) { - if !self.mode.shadow.is_map() { - return; - } - if let Some(_shadow_map) = self.shadow_map.as_mut() { - self.encoder.flush(&mut self.device); - Self::set_depth_clamp(&mut self.device, true); - } - } + // /// Set up shadow rendering. + // pub fn start_shadows(&mut self) { + // if !self.mode.shadow.is_map() { + // return; + // } + // if let Some(_shadow_map) = self.shadow_map.as_mut() { + // self.encoder.flush(&mut self.device); + // Self::set_depth_clamp(&mut self.device, true); + // } + // } - /// Perform all queued draw calls for global.shadows. - pub fn flush_shadows(&mut self) { - if !self.mode.shadow.is_map() { - return; - } - if let Some(_shadow_map) = self.shadow_map.as_mut() { - let point_encoder = &mut self.encoder; - // let point_encoder = &mut shadow_map.point_encoder; - point_encoder.flush(&mut self.device); - // let directed_encoder = &mut shadow_map.directed_encoder; - // directed_encoder.flush(&mut self.device); - // Reset depth clamping. - Self::set_depth_clamp(&mut self.device, false); - } - } + // /// Perform all queued draw calls for global.shadows. + // pub fn flush_shadows(&mut self) { + // if !self.mode.shadow.is_map() { + // return; + // } + // if let Some(_shadow_map) = self.shadow_map.as_mut() { + // let point_encoder = &mut self.encoder; + // // let point_encoder = &mut shadow_map.point_encoder; + // point_encoder.flush(&mut self.device); + // // let directed_encoder = &mut shadow_map.directed_encoder; + // // directed_encoder.flush(&mut self.device); + // // Reset depth clamping. + // Self::set_depth_clamp(&mut self.device, false); + // } + // } /// Perform all queued draw calls for this frame and clean up discarded /// items. @@ -1163,742 +1143,755 @@ impl Renderer { // raw_data).unwrap(), )) } - /// Queue the rendering of the provided skybox model in the upcoming frame. - pub fn render_skybox( - &mut self, - model: &Model, - global: &GlobalModel, - locals: &Consts, - lod: &lod_terrain::LodData, - ) { - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &self.skybox_pipeline.pso, - &skybox::pipe::Data { - vbuf: model.vbuf.clone(), - locals: locals.buf.clone(), - globals: global.globals.buf.clone(), - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - tgt_color: self.tgt_color_view.clone(), - tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), - }, - ); - } + // /// Queue the rendering of the provided skybox model in the upcoming frame. + // pub fn render_skybox( + // &mut self, + // model: &Model, + // global: &GlobalModel, + // locals: &Consts, + // lod: &lod_terrain::LodData, + // ) { + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.skybox_pipeline.pso, + // &skybox::pipe::Data { + // vbuf: model.vbuf.clone(), + // locals: locals.buf.clone(), + // globals: global.globals.buf.clone(), + // noise: (self.noise_tex.srv.clone(), + // self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(), + // lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(), + // lod.horizon.sampler.clone()), tgt_color: + // self.tgt_color_view.clone(), tgt_depth_stencil: + // (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), }, + // ); + // } - /// Queue the rendering of the provided figure model in the upcoming frame. - pub fn render_figure( - &mut self, - model: &figure::FigureModel, - col_lights: &Texture, - global: &GlobalModel, - locals: &Consts, - bones: &Consts, - lod: &lod_terrain::LodData, - ) { - let (point_shadow_maps, directed_shadow_maps) = - if let Some(shadow_map) = &mut self.shadow_map { - ( - ( - shadow_map.point_res.clone(), - shadow_map.point_sampler.clone(), - ), - ( - shadow_map.directed_res.clone(), - shadow_map.directed_sampler.clone(), - ), - ) - } else { - ( - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - ) - }; - let model = &model.opaque; + // /// Queue the rendering of the provided figure model in the upcoming frame. + // pub fn render_figure( + // &mut self, + // model: &figure::FigureModel, + // col_lights: &Texture, + // global: &GlobalModel, + // locals: &Consts, + // bones: &Consts, + // lod: &lod_terrain::LodData, + // ) { + // let (point_shadow_maps, directed_shadow_maps) = + // if let Some(shadow_map) = &mut self.shadow_map { + // ( + // ( + // shadow_map.point_res.clone(), + // shadow_map.point_sampler.clone(), + // ), + // ( + // shadow_map.directed_res.clone(), + // shadow_map.directed_sampler.clone(), + // ), + // ) + // } else { + // ( + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // ) + // }; + // let model = &model.opaque; - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &self.figure_pipeline.pso, - &figure::pipe::Data { - vbuf: model.vbuf.clone(), - col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()), - locals: locals.buf.clone(), - globals: global.globals.buf.clone(), - bones: bones.buf.clone(), - lights: global.lights.buf.clone(), - shadows: global.shadows.buf.clone(), - light_shadows: global.shadow_mats.buf.clone(), - point_shadow_maps, - directed_shadow_maps, - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - tgt_color: self.tgt_color_view.clone(), - tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), - }, - ); - } + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.figure_pipeline.pso, + // &figure::pipe::Data { + // vbuf: model.vbuf.clone(), + // col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()), + // locals: locals.buf.clone(), + // globals: global.globals.buf.clone(), + // bones: bones.buf.clone(), + // lights: global.lights.buf.clone(), + // shadows: global.shadows.buf.clone(), + // light_shadows: global.shadow_mats.buf.clone(), + // point_shadow_maps, + // directed_shadow_maps, + // noise: (self.noise_tex.srv.clone(), + // self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(), + // lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(), + // lod.horizon.sampler.clone()), tgt_color: + // self.tgt_color_view.clone(), tgt_depth_stencil: + // (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), }, + // ); + // } - /// Queue the rendering of the player silhouette in the upcoming frame. - pub fn render_player_shadow( - &mut self, - _model: &figure::FigureModel, - _col_lights: &Texture, - _global: &GlobalModel, - _bones: &Consts, - _lod: &lod_terrain::LodData, - _locals: &Consts, - ) { - // FIXME: Consider reenabling at some point. - /* let (point_shadow_maps, directed_shadow_maps) = - if let Some(shadow_map) = &mut self.shadow_map { - ( - ( - shadow_map.point_res.clone(), - shadow_map.point_sampler.clone(), - ), - ( - shadow_map.directed_res.clone(), - shadow_map.directed_sampler.clone(), - ), - ) - } else { - ( - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - ) - }; - let model = &model.opaque; + // /// Queue the rendering of the player silhouette in the upcoming frame. + // pub fn render_player_shadow( + // &mut self, + // _model: &figure::FigureModel, + // _col_lights: &Texture, + // _global: &GlobalModel, + // _bones: &Consts, + // _lod: &lod_terrain::LodData, + // _locals: &Consts, + // ) { + // // FIXME: Consider reenabling at some point. + // /* let (point_shadow_maps, directed_shadow_maps) = + // if let Some(shadow_map) = &mut self.shadow_map { + // ( + // ( + // shadow_map.point_res.clone(), + // shadow_map.point_sampler.clone(), + // ), + // ( + // shadow_map.directed_res.clone(), + // shadow_map.directed_sampler.clone(), + // ), + // ) + // } else { + // ( + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // ) + // }; + // let model = &model.opaque; - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &self.player_shadow_pipeline.pso, - &figure::pipe::Data { - vbuf: model.vbuf.clone(), - col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()), - locals: locals.buf.clone(), - globals: global.globals.buf.clone(), - bones: bones.buf.clone(), - lights: global.lights.buf.clone(), - shadows: global.shadows.buf.clone(), - light_shadows: global.shadow_mats.buf.clone(), - point_shadow_maps, - directed_shadow_maps, - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - tgt_color: self.tgt_color_view.clone(), - tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (0, 0) */), - }, - ); */ - } + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.player_shadow_pipeline.pso, + // &figure::pipe::Data { + // vbuf: model.vbuf.clone(), + // col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()), + // locals: locals.buf.clone(), + // globals: global.globals.buf.clone(), + // bones: bones.buf.clone(), + // lights: global.lights.buf.clone(), + // shadows: global.shadows.buf.clone(), + // light_shadows: global.shadow_mats.buf.clone(), + // point_shadow_maps, + // directed_shadow_maps, + // noise: (self.noise_tex.srv.clone(), + // self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(), + // lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(), + // lod.horizon.sampler.clone()), tgt_color: + // self.tgt_color_view.clone(), tgt_depth_stencil: + // (self.tgt_depth_stencil_view.clone()/* , (0, 0) */), }, + // ); */ + // } - /// Queue the rendering of the player model in the upcoming frame. - pub fn render_player( - &mut self, - model: &figure::FigureModel, - col_lights: &Texture, - global: &GlobalModel, - locals: &Consts, - bones: &Consts, - lod: &lod_terrain::LodData, - ) { - let (point_shadow_maps, directed_shadow_maps) = - if let Some(shadow_map) = &mut self.shadow_map { - ( - ( - shadow_map.point_res.clone(), - shadow_map.point_sampler.clone(), - ), - ( - shadow_map.directed_res.clone(), - shadow_map.directed_sampler.clone(), - ), - ) - } else { - ( - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - ) - }; - let model = &model.opaque; + // /// Queue the rendering of the player model in the upcoming frame. + // pub fn render_player( + // &mut self, + // model: &figure::FigureModel, + // col_lights: &Texture, + // global: &GlobalModel, + // locals: &Consts, + // bones: &Consts, + // lod: &lod_terrain::LodData, + // ) { + // let (point_shadow_maps, directed_shadow_maps) = + // if let Some(shadow_map) = &mut self.shadow_map { + // ( + // ( + // shadow_map.point_res.clone(), + // shadow_map.point_sampler.clone(), + // ), + // ( + // shadow_map.directed_res.clone(), + // shadow_map.directed_sampler.clone(), + // ), + // ) + // } else { + // ( + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // ) + // }; + // let model = &model.opaque; - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &self.figure_pipeline.pso, - &figure::pipe::Data { - vbuf: model.vbuf.clone(), - col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()), - locals: locals.buf.clone(), - globals: global.globals.buf.clone(), - bones: bones.buf.clone(), - lights: global.lights.buf.clone(), - shadows: global.shadows.buf.clone(), - light_shadows: global.shadow_mats.buf.clone(), - point_shadow_maps, - directed_shadow_maps, - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - tgt_color: self.tgt_color_view.clone(), - tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), - }, - ); - } + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.figure_pipeline.pso, + // &figure::pipe::Data { + // vbuf: model.vbuf.clone(), + // col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()), + // locals: locals.buf.clone(), + // globals: global.globals.buf.clone(), + // bones: bones.buf.clone(), + // lights: global.lights.buf.clone(), + // shadows: global.shadows.buf.clone(), + // light_shadows: global.shadow_mats.buf.clone(), + // point_shadow_maps, + // directed_shadow_maps, + // noise: (self.noise_tex.srv.clone(), + // self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(), + // lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(), + // lod.horizon.sampler.clone()), tgt_color: + // self.tgt_color_view.clone(), tgt_depth_stencil: + // (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), }, + // ); + // } - /// Queue the rendering of the provided terrain chunk model in the upcoming - /// frame. - pub fn render_terrain_chunk( - &mut self, - model: &Model, - col_lights: &Texture, - global: &GlobalModel, - locals: &Consts, - lod: &lod_terrain::LodData, - ) { - let (point_shadow_maps, directed_shadow_maps) = - if let Some(shadow_map) = &mut self.shadow_map { - ( - ( - shadow_map.point_res.clone(), - shadow_map.point_sampler.clone(), - ), - ( - shadow_map.directed_res.clone(), - shadow_map.directed_sampler.clone(), - ), - ) - } else { - ( - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - ) - }; + // /// Queue the rendering of the provided terrain chunk model in the upcoming + // /// frame. + // pub fn render_terrain_chunk( + // &mut self, + // model: &Model, + // col_lights: &Texture, + // global: &GlobalModel, + // locals: &Consts, + // lod: &lod_terrain::LodData, + // ) { + // let (point_shadow_maps, directed_shadow_maps) = + // if let Some(shadow_map) = &mut self.shadow_map { + // ( + // ( + // shadow_map.point_res.clone(), + // shadow_map.point_sampler.clone(), + // ), + // ( + // shadow_map.directed_res.clone(), + // shadow_map.directed_sampler.clone(), + // ), + // ) + // } else { + // ( + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // ) + // }; - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &self.terrain_pipeline.pso, - &terrain::pipe::Data { - vbuf: model.vbuf.clone(), - // TODO: Consider splitting out texture atlas data into a separate vertex buffer, - // since we don't need it for things like global.shadows. - col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()), - locals: locals.buf.clone(), - globals: global.globals.buf.clone(), - lights: global.lights.buf.clone(), - shadows: global.shadows.buf.clone(), - light_shadows: global.shadow_mats.buf.clone(), - point_shadow_maps, - directed_shadow_maps, - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - tgt_color: self.tgt_color_view.clone(), - tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), - }, - ); - } + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.terrain_pipeline.pso, + // &terrain::pipe::Data { + // vbuf: model.vbuf.clone(), + // // TODO: Consider splitting out texture atlas data into a + // separate vertex buffer, // since we don't need it for things + // like global.shadows. col_lights: (col_lights.srv.clone(), + // col_lights.sampler.clone()), locals: locals.buf.clone(), + // globals: global.globals.buf.clone(), + // lights: global.lights.buf.clone(), + // shadows: global.shadows.buf.clone(), + // light_shadows: global.shadow_mats.buf.clone(), + // point_shadow_maps, + // directed_shadow_maps, + // noise: (self.noise_tex.srv.clone(), + // self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(), + // lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(), + // lod.horizon.sampler.clone()), tgt_color: + // self.tgt_color_view.clone(), tgt_depth_stencil: + // (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), }, + // ); + // } - /// Queue the rendering of a shadow map from a point light in the upcoming - /// frame. - pub fn render_shadow_point( - &mut self, - model: &Model, - global: &GlobalModel, - terrain_locals: &Consts, - locals: &Consts, - ) { - if !self.mode.shadow.is_map() { - return; - } - // NOTE: Don't render shadows if the shader is not supported. - let shadow_map = if let Some(shadow_map) = &mut self.shadow_map { - shadow_map - } else { - return; - }; + // /// Queue the rendering of a shadow map from a point light in the upcoming + // /// frame. + // pub fn render_shadow_point( + // &mut self, + // model: &Model, + // global: &GlobalModel, + // terrain_locals: &Consts, + // locals: &Consts, + // ) { + // if !self.mode.shadow.is_map() { + // return; + // } + // // NOTE: Don't render shadows if the shader is not supported. + // let shadow_map = if let Some(shadow_map) = &mut self.shadow_map { + // shadow_map + // } else { + // return; + // }; - // let point_encoder = &mut shadow_map.point_encoder; - let point_encoder = &mut self.encoder; - point_encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &shadow_map.point_pipeline.pso, - &shadow::pipe::Data { - // Terrain vertex stuff - vbuf: model.vbuf.clone(), - locals: terrain_locals.buf.clone(), - globals: global.globals.buf.clone(), + // // let point_encoder = &mut shadow_map.point_encoder; + // let point_encoder = &mut self.encoder; + // point_encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &shadow_map.point_pipeline.pso, + // &shadow::pipe::Data { + // // Terrain vertex stuff + // vbuf: model.vbuf.clone(), + // locals: terrain_locals.buf.clone(), + // globals: global.globals.buf.clone(), - // Shadow stuff - light_shadows: locals.buf.clone(), - tgt_depth_stencil: shadow_map.point_depth_stencil_view.clone(), - }, - ); - } + // // Shadow stuff + // light_shadows: locals.buf.clone(), + // tgt_depth_stencil: shadow_map.point_depth_stencil_view.clone(), + // }, + // ); + // } - /// Queue the rendering of terrain shadow map from all directional lights in - /// the upcoming frame. - pub fn render_terrain_shadow_directed( - &mut self, - model: &Model, - global: &GlobalModel, - terrain_locals: &Consts, - locals: &Consts, - ) { - if !self.mode.shadow.is_map() { - return; - } - // NOTE: Don't render shadows if the shader is not supported. - let shadow_map = if let Some(shadow_map) = &mut self.shadow_map { - shadow_map - } else { - return; - }; + // /// Queue the rendering of terrain shadow map from all directional lights in + // /// the upcoming frame. + // pub fn render_terrain_shadow_directed( + // &mut self, + // model: &Model, + // global: &GlobalModel, + // terrain_locals: &Consts, + // locals: &Consts, + // ) { + // if !self.mode.shadow.is_map() { + // return; + // } + // // NOTE: Don't render shadows if the shader is not supported. + // let shadow_map = if let Some(shadow_map) = &mut self.shadow_map { + // shadow_map + // } else { + // return; + // }; - // let directed_encoder = &mut shadow_map.directed_encoder; - let directed_encoder = &mut self.encoder; - directed_encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &shadow_map.terrain_directed_pipeline.pso, - &shadow::pipe::Data { - // Terrain vertex stuff - vbuf: model.vbuf.clone(), - locals: terrain_locals.buf.clone(), - globals: global.globals.buf.clone(), + // // let directed_encoder = &mut shadow_map.directed_encoder; + // let directed_encoder = &mut self.encoder; + // directed_encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &shadow_map.terrain_directed_pipeline.pso, + // &shadow::pipe::Data { + // // Terrain vertex stuff + // vbuf: model.vbuf.clone(), + // locals: terrain_locals.buf.clone(), + // globals: global.globals.buf.clone(), - // Shadow stuff - light_shadows: locals.buf.clone(), - tgt_depth_stencil: shadow_map.directed_depth_stencil_view.clone(), - }, - ); - } + // // Shadow stuff + // light_shadows: locals.buf.clone(), + // tgt_depth_stencil: + // shadow_map.directed_depth_stencil_view.clone(), }, + // ); + // } - /// Queue the rendering of figure shadow map from all directional lights in - /// the upcoming frame. - pub fn render_figure_shadow_directed( - &mut self, - model: &figure::FigureModel, - global: &GlobalModel, - figure_locals: &Consts, - bones: &Consts, - locals: &Consts, - ) { - if !self.mode.shadow.is_map() { - return; - } - // NOTE: Don't render shadows if the shader is not supported. - let shadow_map = if let Some(shadow_map) = &mut self.shadow_map { - shadow_map - } else { - return; - }; - let model = &model.opaque; + // /// Queue the rendering of figure shadow map from all directional lights in + // /// the upcoming frame. + // pub fn render_figure_shadow_directed( + // &mut self, + // model: &figure::FigureModel, + // global: &GlobalModel, + // figure_locals: &Consts, + // bones: &Consts, + // locals: &Consts, + // ) { + // if !self.mode.shadow.is_map() { + // return; + // } + // // NOTE: Don't render shadows if the shader is not supported. + // let shadow_map = if let Some(shadow_map) = &mut self.shadow_map { + // shadow_map + // } else { + // return; + // }; + // let model = &model.opaque; - // let directed_encoder = &mut shadow_map.directed_encoder; - let directed_encoder = &mut self.encoder; - directed_encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &shadow_map.figure_directed_pipeline.pso, - &shadow::figure_pipe::Data { - // Terrain vertex stuff - vbuf: model.vbuf.clone(), - locals: figure_locals.buf.clone(), - bones: bones.buf.clone(), - globals: global.globals.buf.clone(), + // // let directed_encoder = &mut shadow_map.directed_encoder; + // let directed_encoder = &mut self.encoder; + // directed_encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &shadow_map.figure_directed_pipeline.pso, + // &shadow::figure_pipe::Data { + // // Terrain vertex stuff + // vbuf: model.vbuf.clone(), + // locals: figure_locals.buf.clone(), + // bones: bones.buf.clone(), + // globals: global.globals.buf.clone(), - // Shadow stuff - light_shadows: locals.buf.clone(), - tgt_depth_stencil: shadow_map.directed_depth_stencil_view.clone(), - }, - ); - } + // // Shadow stuff + // light_shadows: locals.buf.clone(), + // tgt_depth_stencil: + // shadow_map.directed_depth_stencil_view.clone(), }, + // ); + // } - /// Queue the rendering of the provided terrain chunk model in the upcoming - /// frame. - pub fn render_fluid_chunk( - &mut self, - model: &Model, - global: &GlobalModel, - locals: &Consts, - lod: &lod_terrain::LodData, - waves: &Texture, - ) { - let (point_shadow_maps, directed_shadow_maps) = - if let Some(shadow_map) = &mut self.shadow_map { - ( - ( - shadow_map.point_res.clone(), - shadow_map.point_sampler.clone(), - ), - ( - shadow_map.directed_res.clone(), - shadow_map.directed_sampler.clone(), - ), - ) - } else { - ( - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - ) - }; + // /// Queue the rendering of the provided terrain chunk model in the upcoming + // /// frame. + // pub fn render_fluid_chunk( + // &mut self, + // model: &Model, + // global: &GlobalModel, + // locals: &Consts, + // lod: &lod_terrain::LodData, + // waves: &Texture, + // ) { + // let (point_shadow_maps, directed_shadow_maps) = + // if let Some(shadow_map) = &mut self.shadow_map { + // ( + // ( + // shadow_map.point_res.clone(), + // shadow_map.point_sampler.clone(), + // ), + // ( + // shadow_map.directed_res.clone(), + // shadow_map.directed_sampler.clone(), + // ), + // ) + // } else { + // ( + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // ) + // }; - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &self.fluid_pipeline.pso, - &fluid::pipe::Data { - vbuf: model.vbuf.clone(), - locals: locals.buf.clone(), - globals: global.globals.buf.clone(), - lights: global.lights.buf.clone(), - shadows: global.shadows.buf.clone(), - light_shadows: global.shadow_mats.buf.clone(), - point_shadow_maps, - directed_shadow_maps, - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - waves: (waves.srv.clone(), waves.sampler.clone()), - tgt_color: self.tgt_color_view.clone(), - tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), - }, - ); - } + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.fluid_pipeline.pso, + // &fluid::pipe::Data { + // vbuf: model.vbuf.clone(), + // locals: locals.buf.clone(), + // globals: global.globals.buf.clone(), + // lights: global.lights.buf.clone(), + // shadows: global.shadows.buf.clone(), + // light_shadows: global.shadow_mats.buf.clone(), + // point_shadow_maps, + // directed_shadow_maps, + // alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), + // horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), + // noise: (self.noise_tex.srv.clone(), + // self.noise_tex.sampler.clone()), waves: (waves.srv.clone(), + // waves.sampler.clone()), tgt_color: + // self.tgt_color_view.clone(), tgt_depth_stencil: + // (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), }, + // ); + // } - /// Queue the rendering of the provided terrain chunk model in the upcoming - /// frame. - pub fn render_sprites( - &mut self, - model: &Model, - col_lights: &Texture, - global: &GlobalModel, - terrain_locals: &Consts, - locals: &Consts, - instances: &Instances, - lod: &lod_terrain::LodData, - ) { - let (point_shadow_maps, directed_shadow_maps) = - if let Some(shadow_map) = &mut self.shadow_map { - ( - ( - shadow_map.point_res.clone(), - shadow_map.point_sampler.clone(), - ), - ( - shadow_map.directed_res.clone(), - shadow_map.directed_sampler.clone(), - ), - ) - } else { - ( - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - ) - }; + // /// Queue the rendering of the provided terrain chunk model in the upcoming + // /// frame. + // pub fn render_sprites( + // &mut self, + // model: &Model, + // col_lights: &Texture, + // global: &GlobalModel, + // terrain_locals: &Consts, + // locals: &Consts, + // instances: &Instances, + // lod: &lod_terrain::LodData, + // ) { + // let (point_shadow_maps, directed_shadow_maps) = + // if let Some(shadow_map) = &mut self.shadow_map { + // ( + // ( + // shadow_map.point_res.clone(), + // shadow_map.point_sampler.clone(), + // ), + // ( + // shadow_map.directed_res.clone(), + // shadow_map.directed_sampler.clone(), + // ), + // ) + // } else { + // ( + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // ) + // }; - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: Some((instances.count() as u32, 0)), - buffer: gfx::IndexBuffer::Auto, - }, - &self.sprite_pipeline.pso, - &sprite::pipe::Data { - vbuf: model.vbuf.clone(), - ibuf: instances.ibuf.clone(), - col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()), - terrain_locals: terrain_locals.buf.clone(), - // NOTE: It would be nice if this wasn't needed and we could use a constant buffer - // offset into the sprite data. Hopefully, when we switch to wgpu we can do this, - // as it offers the exact API we want (the equivalent can be done in OpenGL using - // glBindBufferOffset). - locals: locals.buf.clone(), - globals: global.globals.buf.clone(), - lights: global.lights.buf.clone(), - shadows: global.shadows.buf.clone(), - light_shadows: global.shadow_mats.buf.clone(), - point_shadow_maps, - directed_shadow_maps, - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - tgt_color: self.tgt_color_view.clone(), - tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), - }, - ); - } + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: Some((instances.count() as u32, 0)), + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.sprite_pipeline.pso, + // &sprite::pipe::Data { + // vbuf: model.vbuf.clone(), + // ibuf: instances.ibuf.clone(), + // col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()), + // terrain_locals: terrain_locals.buf.clone(), + // // NOTE: It would be nice if this wasn't needed and we could use + // a constant buffer // offset into the sprite data. Hopefully, + // when we switch to wgpu we can do this, // as it offers the + // exact API we want (the equivalent can be done in OpenGL using + // // glBindBufferOffset). locals: locals.buf.clone(), + // globals: global.globals.buf.clone(), + // lights: global.lights.buf.clone(), + // shadows: global.shadows.buf.clone(), + // light_shadows: global.shadow_mats.buf.clone(), + // point_shadow_maps, + // directed_shadow_maps, + // noise: (self.noise_tex.srv.clone(), + // self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(), + // lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(), + // lod.horizon.sampler.clone()), tgt_color: + // self.tgt_color_view.clone(), tgt_depth_stencil: + // (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), }, + // ); + // } - /// Queue the rendering of the provided LoD terrain model in the upcoming - /// frame. - pub fn render_lod_terrain( - &mut self, - model: &Model, - global: &GlobalModel, - locals: &Consts, - lod: &lod_terrain::LodData, - ) { - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &self.lod_terrain_pipeline.pso, - &lod_terrain::pipe::Data { - vbuf: model.vbuf.clone(), - locals: locals.buf.clone(), - globals: global.globals.buf.clone(), - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - map: (lod.map.srv.clone(), lod.map.sampler.clone()), - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - tgt_color: self.tgt_color_view.clone(), - tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), - }, - ); - } + // /// Queue the rendering of the provided LoD terrain model in the upcoming + // /// frame. + // pub fn render_lod_terrain( + // &mut self, + // model: &Model, + // global: &GlobalModel, + // locals: &Consts, + // lod: &lod_terrain::LodData, + // ) { + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.lod_terrain_pipeline.pso, + // &lod_terrain::pipe::Data { + // vbuf: model.vbuf.clone(), + // locals: locals.buf.clone(), + // globals: global.globals.buf.clone(), + // noise: (self.noise_tex.srv.clone(), + // self.noise_tex.sampler.clone()), map: (lod.map.srv.clone(), + // lod.map.sampler.clone()), alt: (lod.alt.srv.clone(), + // lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(), + // lod.horizon.sampler.clone()), tgt_color: + // self.tgt_color_view.clone(), tgt_depth_stencil: + // (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), }, + // ); + // } - /// Queue the rendering of the provided particle in the upcoming frame. - pub fn render_particles( - &mut self, - model: &Model, - global: &GlobalModel, - instances: &Instances, - lod: &lod_terrain::LodData, - ) { - let (point_shadow_maps, directed_shadow_maps) = - if let Some(shadow_map) = &mut self.shadow_map { - ( - ( - shadow_map.point_res.clone(), - shadow_map.point_sampler.clone(), - ), - ( - shadow_map.directed_res.clone(), - shadow_map.directed_sampler.clone(), - ), - ) - } else { - ( - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - ) - }; + // /// Queue the rendering of the provided particle in the upcoming frame. + // pub fn render_particles( + // &mut self, + // model: &Model, + // global: &GlobalModel, + // instances: &Instances, + // lod: &lod_terrain::LodData, + // ) { + // let (point_shadow_maps, directed_shadow_maps) = + // if let Some(shadow_map) = &mut self.shadow_map { + // ( + // ( + // shadow_map.point_res.clone(), + // shadow_map.point_sampler.clone(), + // ), + // ( + // shadow_map.directed_res.clone(), + // shadow_map.directed_sampler.clone(), + // ), + // ) + // } else { + // ( + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // ) + // }; - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: Some((instances.count() as u32, 0)), - buffer: gfx::IndexBuffer::Auto, - }, - &self.particle_pipeline.pso, - &particle::pipe::Data { - vbuf: model.vbuf.clone(), - ibuf: instances.ibuf.clone(), - globals: global.globals.buf.clone(), - lights: global.lights.buf.clone(), - shadows: global.shadows.buf.clone(), - light_shadows: global.shadow_mats.buf.clone(), - point_shadow_maps, - directed_shadow_maps, - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - tgt_color: self.tgt_color_view.clone(), - tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), - }, - ); - } + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: Some((instances.count() as u32, 0)), + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.particle_pipeline.pso, + // &particle::pipe::Data { + // vbuf: model.vbuf.clone(), + // ibuf: instances.ibuf.clone(), + // globals: global.globals.buf.clone(), + // lights: global.lights.buf.clone(), + // shadows: global.shadows.buf.clone(), + // light_shadows: global.shadow_mats.buf.clone(), + // point_shadow_maps, + // directed_shadow_maps, + // noise: (self.noise_tex.srv.clone(), + // self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(), + // lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(), + // lod.horizon.sampler.clone()), tgt_color: + // self.tgt_color_view.clone(), tgt_depth_stencil: + // (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), }, + // ); + // } - /// Queue the rendering of the provided UI element in the upcoming frame. - pub fn render_ui_element>( - &mut self, - model: Model, - tex: &Texture, - scissor: Aabr, - globals: &Consts, - locals: &Consts, - ) where - F::Surface: gfx::format::TextureSurface, - F::Channel: gfx::format::TextureChannel, - ::DataType: Copy, - { - let Aabr { min, max } = scissor; - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range.start, - end: model.vertex_range.end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &self.ui_pipeline.pso, - &ui::pipe::Data { - vbuf: model.vbuf, - scissor: gfx::Rect { - x: min.x, - y: min.y, - w: max.x - min.x, - h: max.y - min.y, - }, - tex: (tex.srv.clone(), tex.sampler.clone()), - locals: locals.buf.clone(), - globals: globals.buf.clone(), - tgt_color: self.win_color_view.clone(), - tgt_depth: self.win_depth_view.clone(), - }, - ); - } + // /// Queue the rendering of the provided UI element in the upcoming frame. + // pub fn render_ui_element>( + // &mut self, + // model: Model, + // tex: &Texture, + // scissor: Aabr, + // globals: &Consts, + // locals: &Consts, + // ) where + // F::Surface: gfx::format::TextureSurface, + // F::Channel: gfx::format::TextureChannel, + // ::DataType: Copy, + // { + // let Aabr { min, max } = scissor; + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range.start, + // end: model.vertex_range.end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.ui_pipeline.pso, + // &ui::pipe::Data { + // vbuf: model.vbuf, + // scissor: gfx::Rect { + // x: min.x, + // y: min.y, + // w: max.x - min.x, + // h: max.y - min.y, + // }, + // tex: (tex.srv.clone(), tex.sampler.clone()), + // locals: locals.buf.clone(), + // globals: globals.buf.clone(), + // tgt_color: self.win_color_view.clone(), + // tgt_depth: self.win_depth_view.clone(), + // }, + // ); + // } - pub fn render_clouds( - &mut self, - model: &Model, - globals: &Consts, - locals: &Consts, - lod: &lod_terrain::LodData, - ) { - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &self.clouds_pipeline.pso, - &clouds::pipe::Data { - vbuf: model.vbuf.clone(), - locals: locals.buf.clone(), - globals: globals.buf.clone(), - map: (lod.map.srv.clone(), lod.map.sampler.clone()), - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - color_sampler: (self.tgt_color_res.clone(), self.sampler.clone()), - depth_sampler: (self.tgt_depth_res.clone(), self.sampler.clone()), - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - tgt_color: self.tgt_color_pp_view.clone(), - }, - ) - } + // pub fn render_clouds( + // &mut self, + // model: &Model, + // globals: &Consts, + // locals: &Consts, + // lod: &lod_terrain::LodData, + // ) { + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.clouds_pipeline.pso, + // &clouds::pipe::Data { + // vbuf: model.vbuf.clone(), + // locals: locals.buf.clone(), + // globals: globals.buf.clone(), + // map: (lod.map.srv.clone(), lod.map.sampler.clone()), + // alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), + // horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), + // color_sampler: (self.tgt_color_res.clone(), + // self.sampler.clone()), depth_sampler: + // (self.tgt_depth_res.clone(), self.sampler.clone()), noise: + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // tgt_color: self.tgt_color_pp_view.clone(), }, + // ) + // } - pub fn render_post_process( - &mut self, - model: &Model, - globals: &Consts, - locals: &Consts, - lod: &lod_terrain::LodData, - ) { - self.encoder.draw( - &gfx::Slice { - start: model.vertex_range().start, - end: model.vertex_range().end, - base_vertex: 0, - instances: None, - buffer: gfx::IndexBuffer::Auto, - }, - &self.postprocess_pipeline.pso, - &postprocess::pipe::Data { - vbuf: model.vbuf.clone(), - locals: locals.buf.clone(), - globals: globals.buf.clone(), - map: (lod.map.srv.clone(), lod.map.sampler.clone()), - alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), - horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), - color_sampler: (self.tgt_color_res_pp.clone(), self.sampler.clone()), - depth_sampler: (self.tgt_depth_res.clone(), self.sampler.clone()), - noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), - tgt_color: self.win_color_view.clone(), - }, - ) - } + // pub fn render_post_process( + // &mut self, + // model: &Model, + // globals: &Consts, + // locals: &Consts, + // lod: &lod_terrain::LodData, + // ) { + // self.encoder.draw( + // &gfx::Slice { + // start: model.vertex_range().start, + // end: model.vertex_range().end, + // base_vertex: 0, + // instances: None, + // buffer: gfx::IndexBuffer::Auto, + // }, + // &self.postprocess_pipeline.pso, + // &postprocess::pipe::Data { + // vbuf: model.vbuf.clone(), + // locals: locals.buf.clone(), + // globals: globals.buf.clone(), + // map: (lod.map.srv.clone(), lod.map.sampler.clone()), + // alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()), + // horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()), + // color_sampler: (self.tgt_color_res_pp.clone(), + // self.sampler.clone()), depth_sampler: + // (self.tgt_depth_res.clone(), self.sampler.clone()), noise: + // (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), + // tgt_color: self.win_color_view.clone(), }, + // ) + // } } /// Creates all the pipelines used to render. #[allow(clippy::type_complexity)] // TODO: Pending review in #587 fn create_pipelines( - factory: &wgpu::Device, + device: &wgpu::Device, + layouts: &Layouts, shaders: &Shaders, mode: &RenderMode, + sc_desc: &wgpu::SwapChainDescriptor, has_shadow_views: bool, ) -> Result< ( - wgpu::RenderPipeline, - wgpu::RenderPipeline, - wgpu::RenderPipeline, - wgpu::RenderPipeline, - wgpu::RenderPipeline, - wgpu::RenderPipeline, - wgpu::RenderPipeline, - wgpu::RenderPipeline, - wgpu::RenderPipeline, - wgpu::RenderPipeline, - wgpu::RenderPipeline, - Option, - Option, - Option, + skybox::SkyboxPipeline, + figure::FigurePipeline, + terrain::TerrainPipeline, + fluid::FluidPipeline, + sprite::SpritePipeline, + particle::ParticlePipeline, + ui::UIPipeline, + lod_terrain::LodTerrainPipeline, + // TODO: clouds + postprocess::PostProcessPipeline, + //figure::FigurePipeline, + Option, + Option, + Option, ), RenderError, > { + use shaderc::{CompileOptions, Compiler, OptimizationLevel, ResolvedInclude, ShaderKind}; + + let constants = &shaders.constants.read().0; + let globals = &shaders.globals.read().0; + let sky = &shaders.sky.read().0; + let light = &shaders.light.read().0; + let srgb = &shaders.srgb.read().0; + let random = &shaders.random.read().0; + let lod = &shaders.lod.read().0; + let shadows = &shaders.shadows.read().0; + // We dynamically add extra configuration settings to the constants file. let constants = format!( r#" @@ -1911,7 +1904,7 @@ fn create_pipelines( #define SHADOW_MODE {} "#, - shaders.constants.read().0, + constants, // TODO: Configurable vertex/fragment shader preference. "VOXYGEN_COMPUTATION_PREFERENCE_FRAGMENT", match mode.fluid { @@ -1951,11 +1944,11 @@ fn create_pipelines( _ => shaders.cloud_regular, }; - let mut compiler = shaderc::Compiler::new().ok_or(RenderError::ErrorInitializingCompiler)?; - let mut options = shaderc::CompileOptions::new().ok_or(RenderError::ErrorInitializingCompiler)?; - options.set_optimization_level(shaderc::OptimizationLevel::Performance); - options.set_include_callback(move |name,_,shader_name,_| { - Ok(shaderc::ResolvedInclude { + let mut compiler = Compiler::new().ok_or(RenderError::ErrorInitializingCompiler)?; + let mut options = CompileOptions::new().ok_or(RenderError::ErrorInitializingCompiler)?; + options.set_optimization_level(OptimizationLevel::Performance); + options.set_include_callback(move |name, _, shader_name, _| { + Ok(ResolvedInclude { resolved_name: name, content: match name { "constants.glsl" => constants, @@ -1968,9 +1961,9 @@ fn create_pipelines( "lod.glsl" => &lod, "anti-aliasing.glsl" => &anti_alias, "cloud.glsl" => &cloud, - other => return Err(format!("Include {} is not defined",other)) - } - } ) + other => return Err(format!("Include {} is not defined", other)), + }, + }) }); let figure_vert = &shaders.figure_vert.read().0; @@ -1983,188 +1976,371 @@ fn create_pipelines( let directed_shadow_frag = &shaders.directed_shadow_frag.read().0; - // Construct a pipeline for rendering skyboxes - let skybox_pipeline = create_pipeline( - factory, - skybox::pipe::new(), - &shaders.skybox_vert.read().0, - &shaders.skybox_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, + let figure_vert_mod = create_shader_module( + device, + &mut compiler, + figure_vert, + ShaderKind::Vertex, + "figure-vert.glsl", + &options, )?; + let terrain_point_shadow_vert_mod = create_shader_module( + device, + &mut compiler, + terrain_point_shadow_vert, + ShaderKind::Vertex, + "light-shadows-vert.glsl", + &options, + )?; + + let terrain_directed_shadow_vert_mod = create_shader_module( + device, + &mut compiler, + terrain_directed_shadow_vert, + ShaderKind::Vertex, + "light-shadows-directed-vert.glsl", + &options, + )?; + + let figure_directed_shadow_vert_mod = create_shader_module( + device, + &mut compiler, + figure_directed_shadow_vert, + ShaderKind::Vertex, + "light-shadows-figure-vert.glsl", + &options, + )?; + + // TODO: closure to to make calling this easier + + let directed_shadow_frag_mod = create_shader_module( + device, + &mut compiler, + directed_shadow_frag, + ShaderKind::Fragment, + "light-shadows-directed-frag.glsl", + &options, + )?; + + // Construct a pipeline for rendering skyboxes + let skybox_pipeline = skybox::SkyboxPipeline::new( + device, + create_shader_module( + device, + &mut compiler, + shaders.skybox_vert.read().0, + ShaderKind::Vertex, + "skybox-vert.glsl", + &options, + ), + create_shader_module( + device, + &mut compiler, + shaders.skybox_frag.read().0, + ShaderKind::Fragment, + "skybox-frag.glsl", + &options, + ), + sc_desc, + layouts, + mode.aa, + ); + // Construct a pipeline for rendering figures - let figure_pipeline = create_pipeline( - factory, - figure::pipe::new(), - &shaders.figure_vert.read().0, - &shaders.figure_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - )?; + let figure_pipeline = figure::FigurePipeline::new( + device, + &figure_vert_mod, + create_shader_module( + device, + &mut compiler, + shaders.figure_frag.read().0, + ShaderKind::Fragment, + "figure-frag.glsl", + &options, + ), + sc_desc, + layouts, + mode.aa, + ); // Construct a pipeline for rendering terrain - let terrain_pipeline = create_pipeline( - factory, - terrain::pipe::new(), - &shaders.terrain_vert.read().0, - &shaders.terrain_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - )?; + let terrain_pipeline = terrain::TerrainPipeline::new( + device, + create_shader_module( + device, + &mut compiler, + shaders.terrain_vert.read().0, + ShaderKind::Vertex, + "terrain-vert.glsl", + &options, + ), + create_shader_module( + device, + &mut compiler, + shaders.terrain_frag.read().0, + ShaderKind::Fragment, + "terrain-frag.glsl", + &options, + ), + sc_desc, + layouts, + mode.aa, + ); // Construct a pipeline for rendering fluids - let fluid_pipeline = create_pipeline( - factory, - fluid::pipe::new(), - &shaders.fluid_vert.read().0, - &match mode.fluid { - FluidMode::Cheap => shaders.fluid_frag_cheap, - FluidMode::Shiny => shaders.fluid_frag_shiny, - } - .read() - .0, - &include_ctx, - gfx::state::CullFace::Nothing, - )?; + let fluid_pipeline = fluid::FluidPipeline::new( + device, + create_shader_module( + device, + &mut compiler, + shaders.fluid_vert.read().0, + ShaderKind::Vertex, + "terrain-vert.glsl", + &options, + ), + create_shader_module( + device, + &mut compiler, + match mode.fluid { + FluidMode::Cheap => shaders.fluid_frag_cheap.read().0, + FluidMode::Shiny => shaders.fluid_frag_shiny.read().0, + }, + ShaderKind::Fragment, + "fluid-frag.glsl", + &options, + ), + sc_desc, + layouts, + mode.aa, + ); // Construct a pipeline for rendering sprites - let sprite_pipeline = create_pipeline( - factory, - sprite::pipe::new(), - &shaders.sprite_vert.read().0, - &shaders.sprite_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - )?; + let sprite_pipeline = sprite::SpritePipeline::new( + device, + create_shader_module( + device, + &mut compiler, + shaders.sprite_vert.read().0, + ShaderKind::Vertex, + "sprite-vert.glsl", + &options, + ), + create_shader_module( + device, + &mut compiler, + shaders.sprite_frag.read().0, + ShaderKind::Fragment, + "sprite-frag.glsl", + &options, + ), + sc_desc, + layouts, + mode.aa, + ); // Construct a pipeline for rendering particles - let particle_pipeline = create_pipeline( - factory, - particle::pipe::new(), - &shaders.particle_vert.read().0, - &shaders.particle_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - )?; + let particle_pipeline = particle::ParticlePipeline::new( + device, + create_shader_module( + device, + &mut compiler, + shaders.particle_vert.read().0, + ShaderKind::Vertex, + "particle-vert.glsl", + &options, + ), + create_shader_module( + device, + &mut compiler, + shaders.particle_frag.read().0, + ShaderKind::Fragment, + "particle-frag.glsl", + &options, + ), + sc_desc, + layouts, + mode.aa, + ); // Construct a pipeline for rendering UI elements - let ui_pipeline = create_pipeline( - factory, - ui::pipe::new(), - &shaders.ui_vert.read().0, - &shaders.ui_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - )?; + let ui_pipeline = ui::UIPipeline::new( + device, + create_shader_module( + device, + &mut compiler, + shaders.ui_vert.read().0, + ShaderKind::Vertex, + "ui-vert.glsl", + &options, + ), + create_shader_module( + device, + &mut compiler, + shaders.ui_frag.read().0, + ShaderKind::Fragment, + "ui-frag.glsl", + &options, + ), + sc_desc, + layouts, + mode.aa, + ); // Construct a pipeline for rendering terrain - let lod_terrain_pipeline = create_pipeline( - factory, - lod_terrain::pipe::new(), - &shaders.lod_terrain_vert.read().0, - &shaders.lod_terrain_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - )?; + let lod_terrain_pipeline = lod_terrain::LodTerrainPipeline::new( + device, + create_shader_module( + device, + &mut compiler, + shaders.lod_terrain_vert.read().0, + ShaderKind::Vertex, + "lod-terrain-vert.glsl", + &options, + ), + create_shader_module( + device, + &mut compiler, + shaders.lod_terrain_frag.read().0, + ShaderKind::Fragment, + "lod-terrain-frag.glsl", + &options, + ), + sc_desc, + layouts, + mode.aa, + ); // Construct a pipeline for rendering our clouds (a kind of post-processing) - let clouds_pipeline = create_pipeline( - factory, - clouds::pipe::new(), - &shaders.clouds_vert.read().0, - &shaders.clouds_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - )?; + // let clouds_pipeline = create_pipeline( + // factory, + // clouds::pipe::new(), + // &Glsl::load_watched("voxygen.shaders.clouds-vert", + // shader_reload_indicator).unwrap(), &Glsl::load_watched("voxygen. + // shaders.clouds-frag", shader_reload_indicator).unwrap(), + // &include_ctx, + // gfx::state::CullFace::Back, + // )?; // Construct a pipeline for rendering our post-processing - let postprocess_pipeline = create_pipeline( - factory, - postprocess::pipe::new(), - &shaders.postprocess_vert.read().0, - &shaders.postprocess_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - )?; + let postprocess_pipeline = postprocess::PostProcessPipeline::new( + device, + create_shader_module( + device, + &mut compiler, + shaders.postprocess_vert.read().0, + ShaderKind::Vertex, + "postprocess-vert.glsl", + &options, + ), + create_shader_module( + device, + &mut compiler, + shaders.postprocess_frag.read().0, + ShaderKind::Fragment, + "postprocess-frag.glsl", + &options, + ), + sc_desc, + layouts, + mode.aa, + ); - // Construct a pipeline for rendering the player silhouette - let player_shadow_pipeline = create_pipeline( - factory, - figure::pipe::Init { - tgt_depth_stencil: (gfx::preset::depth::PASS_TEST/*, - Stencil::new( - Comparison::Equal, - 0xff, - (StencilOp::Keep, StencilOp::Keep, StencilOp::Keep), - ),*/), - ..figure::pipe::new() - }, - &shaders.figure_vert.read().0, - &shaders.player_shadow_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - )?; + // Consider reenabling at some time in the future + // + // // Construct a pipeline for rendering the player silhouette + // let player_shadow_pipeline = create_pipeline( + // factory, + // figure::pipe::Init { + // tgt_depth_stencil: (gfx::preset::depth::PASS_TEST/*, + // Stencil::new( + // Comparison::Equal, + // 0xff, + // (StencilOp::Keep, StencilOp::Keep, StencilOp::Keep), + // ),*/), + // ..figure::pipe::new() + // }, + // &figure_vert, + // &Glsl::load_watched( + // "voxygen.shaders.player-shadow-frag", + // shader_reload_indicator, + // ) + // .unwrap(), + // &include_ctx, + // gfx::state::CullFace::Back, + // )?; - // Construct a pipeline for rendering point light terrain shadow maps. - let point_shadow_pipeline = match create_shadow_pipeline( - factory, - shadow::pipe::new(), - &shaders.terrain_point_shadow_vert.read().0, - Some(&shaders.light_shadows_geom.read().0), - &shaders.light_shadows_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - None, // Some(gfx::state::Offset(2, 0)) - ) { - Ok(pipe) => Some(pipe), - Err(err) => { - warn!("Could not load point shadow map pipeline: {:?}", err); - None - }, - }; + // Sharp can fix it later ;) + // + // // Construct a pipeline for rendering point light terrain shadow maps. + // let point_shadow_pipeline = match create_shadow_pipeline( + // factory, + // shadow::pipe::new(), + // &terrain_point_shadow_vert, + // Some( + // &Glsl::load_watched( + // "voxygen.shaders.light-shadows-geom", + // shader_reload_indicator, + // ) + // .unwrap(), + // ), + // &Glsl::load_watched( + // "voxygen.shaders.light-shadows-frag", + // shader_reload_indicator, + // ) + // .unwrap(), + // &include_ctx, + // gfx::state::CullFace::Back, + // None, // Some(gfx::state::Offset(2, 0)) + // ) { + // Ok(pipe) => Some(pipe), + // Err(err) => { + // warn!("Could not load point shadow map pipeline: {:?}", err); + // None + // }, + // }; - // Construct a pipeline for rendering directional light terrain shadow maps. - let terrain_directed_shadow_pipeline = match create_shadow_pipeline( - factory, - shadow::pipe::new(), - &shaders.terrain_directed_shadow_vert.read().0, - None, - &shaders.directed_shadow_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - None, // Some(gfx::state::Offset(2, 1)) - ) { - Ok(pipe) => Some(pipe), - Err(err) => { - warn!( - "Could not load directed terrain shadow map pipeline: {:?}", - err - ); - None - }, - }; + // // Construct a pipeline for rendering directional light terrain shadow maps. + // let terrain_directed_shadow_pipeline = match create_shadow_pipeline( + // factory, + // shadow::pipe::new(), + // &terrain_directed_shadow_vert, + // None, + // &directed_shadow_frag, + // &include_ctx, + // gfx::state::CullFace::Back, + // None, // Some(gfx::state::Offset(2, 1)) + // ) { + // Ok(pipe) => Some(pipe), + // Err(err) => { + // warn!( + // "Could not load directed terrain shadow map pipeline: {:?}", + // err + // ); + // None + // }, + // }; - // Construct a pipeline for rendering directional light figure shadow maps. - let figure_directed_shadow_pipeline = match create_shadow_pipeline( - factory, - shadow::figure_pipe::new(), - &shaders.figure_directed_shadow_vert.read().0, - None, - &shaders.directed_shadow_frag.read().0, - &include_ctx, - gfx::state::CullFace::Back, - None, // Some(gfx::state::Offset(2, 1)) - ) { - Ok(pipe) => Some(pipe), - Err(err) => { - warn!( - "Could not load directed figure shadow map pipeline: {:?}", - err - ); - None - }, - }; + // // Construct a pipeline for rendering directional light figure shadow maps. + // let figure_directed_shadow_pipeline = match create_shadow_pipeline( + // factory, + // shadow::figure_pipe::new(), + // &figure_directed_shadow_vert, + // None, + // &directed_shadow_frag, + // &include_ctx, + // gfx::state::CullFace::Back, + // None, // Some(gfx::state::Offset(2, 1)) + // ) { + // Ok(pipe) => Some(pipe), + // Err(err) => { + // warn!( + // "Could not load directed figure shadow map pipeline: {:?}", + // err + // ); + // None + // }, + // }; Ok(( skybox_pipeline, @@ -2177,61 +2353,24 @@ fn create_pipelines( lod_terrain_pipeline, clouds_pipeline, postprocess_pipeline, - player_shadow_pipeline, - point_shadow_pipeline, - terrain_directed_shadow_pipeline, - figure_directed_shadow_pipeline, + // player_shadow_pipeline, + None, + None, + None, )) } -/// Create a new pipeline from the provided vertex shader and fragment shader. -fn create_pipeline( +pub fn create_shader_module( device: &wgpu::Device, - desc: &wgpu::RenderPipelineDescriptor -) -> wgpu::RenderPipeline { - device.create_render_pipeline(desc) -} - -/// Create a new shadow map pipeline. -fn create_shadow_pipeline( - factory: &mut gfx_backend::Factory, - pipe: P, - vs: &str, - gs: Option<&str>, - fs: &str, - ctx: &IncludeContext, - cull_face: gfx::state::CullFace, - offset: Option, -) -> Result, RenderError> { - let vs = ctx.expand(vs)?; - let gs = gs.map(|gs| ctx.expand(gs)).transpose()?; - let fs = ctx.expand(fs)?; - - let shader_set = if let Some(gs) = gs { - factory.create_shader_set_geometry(vs.as_bytes(), gs.as_bytes(), fs.as_bytes())? - } else { - factory.create_shader_set(vs.as_bytes(), fs.as_bytes())? - }; - - Ok(GfxPipeline { - pso: factory.create_pipeline_state( - &shader_set, - gfx::Primitive::TriangleList, - gfx::state::Rasterizer { - front_face: gfx::state::FrontFace::CounterClockwise, - // Second-depth shadow mapping: should help reduce z-fighting provided all objects - // are "watertight" (every triangle edge is shared with at most one other - // triangle); this *should* be true for Veloren. - cull_face: match cull_face { - gfx::state::CullFace::Front => gfx::state::CullFace::Back, - gfx::state::CullFace::Back => gfx::state::CullFace::Front, - gfx::state::CullFace::Nothing => gfx::state::CullFace::Nothing, - }, - method: gfx::state::RasterMethod::Fill, - offset, - samples: None, - }, - pipe, - )?, - }) + compiler: &mut shaderc::Compiler, + source: &str, + kind: shaderc::ShaderKind, + file_name: &str, + options: &shaderc::CompileOptions, +) -> Result { + use std::borrow::Cow; + + let spv = compiler.compile_into_spirv(source, kind, file_name, "main", Some(options))?; + + Ok(device.create_shader_module(wgpu::ShaderModule::SpirV(Cow::Bowrrowed(spv.as_binary())))) }