├── .github
└── workflows
│ └── rust.yml
├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── README.md
├── assets
├── audio
│ ├── box_join.ogg
│ ├── finish.ogg
│ ├── level1.ogg
│ ├── level10.ogg
│ ├── level11.ogg
│ ├── level12.ogg
│ ├── level2.ogg
│ ├── level3.ogg
│ ├── level4.ogg
│ ├── level5.ogg
│ ├── level6.ogg
│ ├── level7.ogg
│ ├── level8.ogg
│ ├── level9.ogg
│ ├── main_menu_background.ogg
│ └── movement.ogg
├── fonts
│ ├── raleway.ttf
│ └── roboto.ttf
└── images
│ ├── avatar.png
│ ├── box-default-2.png
│ ├── box-default-3.png
│ ├── button-on.png
│ ├── button.png
│ ├── buttons
│ ├── back.png
│ ├── button.png
│ ├── credits-button.png
│ ├── done-2.png
│ ├── done.png
│ ├── levels
│ │ ├── back.png
│ │ ├── level-1.png
│ │ ├── level-10.png
│ │ ├── level-11.png
│ │ ├── level-12.png
│ │ ├── level-2.png
│ │ ├── level-3.png
│ │ ├── level-4.png
│ │ ├── level-5.png
│ │ ├── level-6.png
│ │ ├── level-7.png
│ │ ├── level-8.png
│ │ ├── level-9.png
│ │ └── levels.png
│ ├── next-level.png
│ ├── next.png
│ ├── play-button.png
│ ├── prev.png
│ ├── restart.png
│ └── settings-button.png
│ ├── choose-wisely.png
│ ├── code.png
│ ├── controls-2.png
│ ├── controls.png
│ ├── controls.psd
│ ├── credits.png
│ ├── enter-the-code.png
│ ├── final.png
│ ├── finish-arrow.png
│ ├── finish-old.png
│ ├── finish.png
│ ├── finish.psd
│ ├── overlay-down.png
│ ├── overlay-gravity.png
│ ├── overlay-left.png
│ ├── overlay-right.png
│ ├── overlay-undo.png
│ ├── overlay-up.png
│ ├── overlay-x2.png
│ ├── overlay-x3.png
│ ├── overlay-x4.png
│ ├── overlay-x9.png
│ ├── preview.png
│ ├── robot-preview-0.png
│ ├── robot-preview-1.png
│ ├── robot-preview-2.png
│ ├── robot-preview-3.png
│ ├── robot-preview-4.png
│ ├── robot-preview-5.png
│ ├── robot-preview-6.png
│ ├── robot-states-1.png
│ ├── robot-states-2.png
│ ├── robot-states-3.png
│ ├── robot-states-4.png
│ ├── robot-states-5.png
│ ├── robot-states-6.png
│ ├── robot-states-emissive.png
│ ├── robot-states.psd
│ ├── robot.png
│ ├── title.png
│ └── you-did-it.png
├── index.html
├── post-processing
├── Cargo.lock
├── Cargo.toml
└── src
│ ├── bloom_node.rs
│ ├── color_material_custom.rs
│ ├── lib.rs
│ ├── lights.rs
│ ├── main_pass_2d_node.rs
│ ├── shaders
│ ├── color_material_custom.wgsl
│ ├── default.vert
│ ├── downscaling.frag
│ ├── tonemapping.frag
│ └── upscaling.frag
│ ├── tone_mapping_node.rs
│ └── utils.rs
└── src
├── core
├── audio.rs
├── camera.rs
├── material.rs
├── mod.rs
├── scene_builder
│ ├── boundaries.rs
│ ├── combobox.rs
│ ├── door.rs
│ ├── elevator.rs
│ ├── mod.rs
│ ├── player.rs
│ ├── spawn_point.rs
│ └── wall.rs
└── scene_objects
│ ├── collision_groups.rs
│ ├── combobox.rs
│ ├── door.rs
│ ├── elevator.rs
│ ├── mod.rs
│ └── player.rs
├── game.rs
├── gui
├── buttons.rs
├── credits_menu.rs
├── game_menu.rs
├── level_completed_menu.rs
├── level_menu.rs
├── main_menu.rs
└── mod.rs
├── levels
├── level1.rs
├── level10.rs
├── level11.rs
├── level12.rs
├── level2.rs
├── level3.rs
├── level4.rs
├── level5.rs
├── level6.rs
├── level7.rs
├── level8.rs
├── level9.rs
└── mod.rs
├── main.rs
├── states.rs
└── utils
├── direction.rs
├── fps.rs
└── mod.rs
/.github/workflows/rust.yml:
--------------------------------------------------------------------------------
1 | name: Rust
2 |
3 | on:
4 | push:
5 | branches: [ "master" ]
6 |
7 | env:
8 | CARGO_TERM_COLOR: always
9 |
10 | jobs:
11 | build:
12 |
13 | runs-on: self-hosted
14 |
15 | steps:
16 | - uses: actions/checkout@v3
17 | - name: Installing wasm
18 | run: rustup target install wasm32-unknown-unknown
19 | - name: Installing wasm cli
20 | run: cargo install -f wasm-bindgen-cli
21 | - name: Build
22 | run: cargo build --target wasm32-unknown-unknown --release
23 | - name: Building wasm
24 | run: wasm-bindgen --out-dir ./out/ --target web ./target/wasm32-unknown-unknown/release/combobox-game.wasm
25 | - name: Push wasm build artifacts to git hub pages branch
26 | run: |
27 | git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}"
28 | git config --global user.email "username@users.noreply.github.com"
29 | git clone https://github.com/${{ github.repository }} build
30 | cd build
31 | git checkout gh-pages
32 | del -r .\assets; cp -r ..\assets .\assets
33 | del -r .\index.html; cp ..\index.html .
34 | del -r .\out; cp -r ..\out .\out
35 | git add .
36 | git commit -m "Git hub pages update"
37 | git push
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/target/
2 | target/
3 | .idea/
4 | out/
5 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "combobox-game"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = { version="0.8.0", default-features=false, features=["bevy_ui", "bevy_text", "bevy_winit", "png", "filesystem_watcher"] }
10 | post-processing={ path="post-processing" }
11 | bevy_rapier2d = "0.16.1"
12 | rapier2d = "0.14.0"
13 | bevy_kira_audio = "0.12.0"
14 |
15 | [target.wasm32-unknown-unknown]
16 | runner = "wasm-server-runner"
17 |
18 | [profile.dev.package."*"]
19 | opt-level = 3
20 |
21 | [profile.dev]
22 | opt-level = 1
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Combobox
2 |
3 | Our game made for [Bevy Jam #2](https://itch.io/jam/bevy-jam-2)!
4 |
5 | P.S. Combobox game got **4th** /85 place!
6 |
7 | # Check out our current demo
8 |
9 | Demo can be found on [itches.io](https://combobox-game.itch.io/combobox) or on [github pages](https://comboboxgame.github.io/Combobox/)
10 |
--------------------------------------------------------------------------------
/assets/audio/box_join.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/box_join.ogg
--------------------------------------------------------------------------------
/assets/audio/finish.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/finish.ogg
--------------------------------------------------------------------------------
/assets/audio/level1.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level1.ogg
--------------------------------------------------------------------------------
/assets/audio/level10.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level10.ogg
--------------------------------------------------------------------------------
/assets/audio/level11.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level11.ogg
--------------------------------------------------------------------------------
/assets/audio/level12.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level12.ogg
--------------------------------------------------------------------------------
/assets/audio/level2.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level2.ogg
--------------------------------------------------------------------------------
/assets/audio/level3.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level3.ogg
--------------------------------------------------------------------------------
/assets/audio/level4.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level4.ogg
--------------------------------------------------------------------------------
/assets/audio/level5.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level5.ogg
--------------------------------------------------------------------------------
/assets/audio/level6.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level6.ogg
--------------------------------------------------------------------------------
/assets/audio/level7.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level7.ogg
--------------------------------------------------------------------------------
/assets/audio/level8.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level8.ogg
--------------------------------------------------------------------------------
/assets/audio/level9.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/level9.ogg
--------------------------------------------------------------------------------
/assets/audio/main_menu_background.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/main_menu_background.ogg
--------------------------------------------------------------------------------
/assets/audio/movement.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/audio/movement.ogg
--------------------------------------------------------------------------------
/assets/fonts/raleway.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/fonts/raleway.ttf
--------------------------------------------------------------------------------
/assets/fonts/roboto.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/fonts/roboto.ttf
--------------------------------------------------------------------------------
/assets/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/avatar.png
--------------------------------------------------------------------------------
/assets/images/box-default-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/box-default-2.png
--------------------------------------------------------------------------------
/assets/images/box-default-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/box-default-3.png
--------------------------------------------------------------------------------
/assets/images/button-on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/button-on.png
--------------------------------------------------------------------------------
/assets/images/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/button.png
--------------------------------------------------------------------------------
/assets/images/buttons/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/back.png
--------------------------------------------------------------------------------
/assets/images/buttons/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/button.png
--------------------------------------------------------------------------------
/assets/images/buttons/credits-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/credits-button.png
--------------------------------------------------------------------------------
/assets/images/buttons/done-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/done-2.png
--------------------------------------------------------------------------------
/assets/images/buttons/done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/done.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/back.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-1.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-10.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-11.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-12.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-2.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-3.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-4.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-5.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-6.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-7.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-8.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/level-9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/level-9.png
--------------------------------------------------------------------------------
/assets/images/buttons/levels/levels.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/levels/levels.png
--------------------------------------------------------------------------------
/assets/images/buttons/next-level.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/next-level.png
--------------------------------------------------------------------------------
/assets/images/buttons/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/next.png
--------------------------------------------------------------------------------
/assets/images/buttons/play-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/play-button.png
--------------------------------------------------------------------------------
/assets/images/buttons/prev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/prev.png
--------------------------------------------------------------------------------
/assets/images/buttons/restart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/restart.png
--------------------------------------------------------------------------------
/assets/images/buttons/settings-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/buttons/settings-button.png
--------------------------------------------------------------------------------
/assets/images/choose-wisely.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/choose-wisely.png
--------------------------------------------------------------------------------
/assets/images/code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/code.png
--------------------------------------------------------------------------------
/assets/images/controls-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/controls-2.png
--------------------------------------------------------------------------------
/assets/images/controls.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/controls.png
--------------------------------------------------------------------------------
/assets/images/controls.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/controls.psd
--------------------------------------------------------------------------------
/assets/images/credits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/credits.png
--------------------------------------------------------------------------------
/assets/images/enter-the-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/enter-the-code.png
--------------------------------------------------------------------------------
/assets/images/final.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/final.png
--------------------------------------------------------------------------------
/assets/images/finish-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/finish-arrow.png
--------------------------------------------------------------------------------
/assets/images/finish-old.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/finish-old.png
--------------------------------------------------------------------------------
/assets/images/finish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/finish.png
--------------------------------------------------------------------------------
/assets/images/finish.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/finish.psd
--------------------------------------------------------------------------------
/assets/images/overlay-down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/overlay-down.png
--------------------------------------------------------------------------------
/assets/images/overlay-gravity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/overlay-gravity.png
--------------------------------------------------------------------------------
/assets/images/overlay-left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/overlay-left.png
--------------------------------------------------------------------------------
/assets/images/overlay-right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/overlay-right.png
--------------------------------------------------------------------------------
/assets/images/overlay-undo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/overlay-undo.png
--------------------------------------------------------------------------------
/assets/images/overlay-up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/overlay-up.png
--------------------------------------------------------------------------------
/assets/images/overlay-x2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/overlay-x2.png
--------------------------------------------------------------------------------
/assets/images/overlay-x3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/overlay-x3.png
--------------------------------------------------------------------------------
/assets/images/overlay-x4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/overlay-x4.png
--------------------------------------------------------------------------------
/assets/images/overlay-x9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/overlay-x9.png
--------------------------------------------------------------------------------
/assets/images/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/preview.png
--------------------------------------------------------------------------------
/assets/images/robot-preview-0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-preview-0.png
--------------------------------------------------------------------------------
/assets/images/robot-preview-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-preview-1.png
--------------------------------------------------------------------------------
/assets/images/robot-preview-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-preview-2.png
--------------------------------------------------------------------------------
/assets/images/robot-preview-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-preview-3.png
--------------------------------------------------------------------------------
/assets/images/robot-preview-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-preview-4.png
--------------------------------------------------------------------------------
/assets/images/robot-preview-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-preview-5.png
--------------------------------------------------------------------------------
/assets/images/robot-preview-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-preview-6.png
--------------------------------------------------------------------------------
/assets/images/robot-states-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-states-1.png
--------------------------------------------------------------------------------
/assets/images/robot-states-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-states-2.png
--------------------------------------------------------------------------------
/assets/images/robot-states-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-states-3.png
--------------------------------------------------------------------------------
/assets/images/robot-states-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-states-4.png
--------------------------------------------------------------------------------
/assets/images/robot-states-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-states-5.png
--------------------------------------------------------------------------------
/assets/images/robot-states-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-states-6.png
--------------------------------------------------------------------------------
/assets/images/robot-states-emissive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-states-emissive.png
--------------------------------------------------------------------------------
/assets/images/robot-states.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot-states.psd
--------------------------------------------------------------------------------
/assets/images/robot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/robot.png
--------------------------------------------------------------------------------
/assets/images/title.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/title.png
--------------------------------------------------------------------------------
/assets/images/you-did-it.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ComboboxGame/Combobox/3c0cd0a4945fe061a7b5ad5d9ccab0d9199ad05d/assets/images/you-did-it.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
48 |
49 |
50 |
51 |
52 |
53 | Combobox!
54 |
55 |
58 |
59 |
68 |
69 |
--------------------------------------------------------------------------------
/post-processing/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "post-processing"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | bevy = { version="0.8.0", default-features=false, features=["bevy_core_pipeline", "bevy_render", "bevy_asset", "bevy_sprite", "bevy_ui"] }
10 | wgpu = "0.13.1"
11 | bytemuck = "1.12.0"
12 | bitflags = "1.3.2"
13 |
--------------------------------------------------------------------------------
/post-processing/src/color_material_custom.rs:
--------------------------------------------------------------------------------
1 | use bevy::app::{App, Plugin};
2 | use bevy::asset::{Assets, Handle};
3 | use bevy::math::Vec4;
4 |
5 | use bevy::reflect::TypeUuid;
6 | use bevy::render::mesh::MeshVertexBufferLayout;
7 | use bevy::render::{
8 | color::Color, render_asset::RenderAssets, render_resource::*, texture::Image,
9 | };
10 |
11 | use bevy::sprite::{
12 | Material2d, Material2dKey, Material2dPlugin,
13 | };
14 | use crate::{CUSTOM_MATERIAL, PointLightsUniform};
15 |
16 | #[derive(Default)]
17 | pub struct ColorMaterialCustomPlugin;
18 |
19 | impl Plugin for ColorMaterialCustomPlugin {
20 | fn build(&self, app: &mut App) {
21 | app.add_plugin(Material2dPlugin::::default());
22 |
23 | app.world
24 | .resource_mut::>()
25 | .set_untracked(
26 | Handle::::default(),
27 | ColorMaterialCustom {
28 | color: Color::rgb(1.0, 0.0, 1.0),
29 | ..Default::default()
30 | },
31 | );
32 | }
33 | }
34 |
35 | /// A [2d material](Material2d) that renders [2d meshes](crate::Mesh2dHandle) with a texture tinted by a uniform color
36 | #[derive(AsBindGroup, Debug, Clone, TypeUuid)]
37 | #[uuid = "e228a544-e3ca-4e1e-ba9d-4d8bc1ad8c19"]
38 | #[uniform(0, ColorMaterialCustomUniform)]
39 | pub struct ColorMaterialCustom {
40 | pub color: Color,
41 | pub lights: PointLightsUniform,
42 | #[texture(1)]
43 | #[sampler(2)]
44 | pub texture: Option>,
45 |
46 | #[texture(3)]
47 | #[sampler(4)]
48 | pub emissive: Option>,
49 |
50 | #[texture(5)]
51 | #[sampler(6)]
52 | pub overlay: Option>,
53 | }
54 |
55 | impl Default for ColorMaterialCustom {
56 | fn default() -> Self {
57 | ColorMaterialCustom {
58 | color: Color::WHITE,
59 | lights: PointLightsUniform::default(),
60 | texture: None,
61 | emissive: None,
62 | overlay: None,
63 | }
64 | }
65 | }
66 |
67 | impl From for ColorMaterialCustom {
68 | fn from(color: Color) -> Self {
69 | ColorMaterialCustom {
70 | color,
71 | ..Default::default()
72 | }
73 | }
74 | }
75 |
76 | impl From> for ColorMaterialCustom {
77 | fn from(texture: Handle) -> Self {
78 | ColorMaterialCustom {
79 | texture: Some(texture),
80 | ..Default::default()
81 | }
82 | }
83 | }
84 |
85 | impl From<(Handle, Option>, Option>)> for ColorMaterialCustom {
86 | fn from(texture: (Handle, Option>, Option>)) -> Self {
87 | ColorMaterialCustom {
88 | texture: Some(texture.0),
89 | emissive: texture.1,
90 | overlay: texture.2,
91 | ..Default::default()
92 | }
93 | }
94 | }
95 |
96 | /// The GPU representation of the uniform data of a [`ColorMaterialCustom`].
97 | #[derive(Clone, Default, ShaderType)]
98 | pub struct ColorMaterialCustomUniform {
99 | pub color: Vec4,
100 | pub flags: u32,
101 | pub lights: PointLightsUniform,
102 | }
103 |
104 | // NOTE: These must match the bit flags in bevy_sprite/src/mesh2d/color_material.wgsl!
105 | bitflags::bitflags! {
106 | #[repr(transparent)]
107 | pub struct ColorMaterialFlagsCustom: u32 {
108 | const TEXTURE = (1 << 0);
109 | const EMISSIVE = (1 << 1);
110 | const OVERLAY = (1 << 2);
111 | const NONE = 0;
112 | const UNINITIALIZED = 0xFFFF;
113 | }
114 | }
115 |
116 | impl AsBindGroupShaderType for ColorMaterialCustom {
117 | fn as_bind_group_shader_type(
118 | &self,
119 | _images: &RenderAssets,
120 | ) -> ColorMaterialCustomUniform {
121 | let mut flags = ColorMaterialFlagsCustom::NONE;
122 | if self.texture.is_some() {
123 | flags |= ColorMaterialFlagsCustom::TEXTURE;
124 | }
125 | if self.emissive.is_some() {
126 | flags |= ColorMaterialFlagsCustom::EMISSIVE;
127 | }
128 | if self.overlay.is_some() {
129 | flags |= ColorMaterialFlagsCustom::OVERLAY;
130 | }
131 |
132 | ColorMaterialCustomUniform {
133 | color: self.color.as_linear_rgba_f32().into(),
134 | flags: flags.bits(),
135 | lights: self.lights.clone(),
136 | }
137 | }
138 | }
139 |
140 | impl Material2d for ColorMaterialCustom {
141 | fn fragment_shader() -> ShaderRef {
142 | CUSTOM_MATERIAL.typed().into()
143 | }
144 |
145 | fn specialize(
146 | descriptor: &mut RenderPipelineDescriptor,
147 | _layout: &MeshVertexBufferLayout,
148 | _key: Material2dKey,
149 | ) -> Result<(), SpecializedMeshPipelineError> {
150 | // HDR texture
151 | (*descriptor.fragment.as_mut().unwrap()).targets.clear();
152 | (*descriptor.fragment.as_mut().unwrap())
153 | .targets
154 | .push(Some(ColorTargetState {
155 | format: TextureFormat::Rg11b10Float,
156 | blend: Some(BlendState::ALPHA_BLENDING),
157 | write_mask: ColorWrites::ALL,
158 | }));
159 | descriptor.primitive.cull_mode = None;
160 |
161 | Ok(())
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/post-processing/src/lib.rs:
--------------------------------------------------------------------------------
1 | use bevy::app::{App, CoreStage, Plugin};
2 | use bevy::core_pipeline::core_2d::graph;
3 | use bevy::core_pipeline::core_2d::MainPass2dNode;
4 | use bevy::ecs::prelude::*;
5 | use bevy::prelude::{Assets, HandleUntyped, Msaa, Shader};
6 | use bevy::reflect::TypeUuid;
7 | use bevy::render::{
8 | render_graph::RenderGraph,
9 | RenderApp, RenderStage,
10 | };
11 | use bevy::render::camera::ExtractedCamera;
12 | use bevy::render::render_resource::{Extent3d, Operations, ShaderStage, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, TextureView, UniformBuffer};
13 | use bevy::render::renderer::RenderDevice;
14 | use bevy::render::texture::TextureCache;
15 | use bevy::render::view::WindowSystem;
16 | use bevy::ui::draw_ui_graph;
17 | use bevy::utils::HashMap;
18 | pub use color_material_custom::ColorMaterialCustom;
19 | pub use lights::*;
20 | use wgpu::{Color, RenderPassColorAttachment};
21 |
22 | use crate::bloom_node::*;
23 | use crate::color_material_custom::*;
24 | use crate::main_pass_2d_node::MainPass2dNodeCustom;
25 | use crate::tone_mapping_node::*;
26 |
27 | mod bloom_node;
28 | mod color_material_custom;
29 | mod main_pass_2d_node;
30 | mod tone_mapping_node;
31 | mod lights;
32 | mod utils;
33 |
34 |
35 | pub struct Core2dCustomPlugin;
36 |
37 | pub const CUSTOM_DEFAULT_VERT: HandleUntyped =
38 | HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 8454671400261990324);
39 | pub const CUSTOM_UPSCALING: HandleUntyped =
40 | HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 8678671400261345394);
41 | pub const CUSTOM_DOWNSCALING: HandleUntyped =
42 | HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 8214674567261990328);
43 | pub const CUSTOM_TONEMAPPING: HandleUntyped =
44 | HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 8994546787261990326);
45 | pub const CUSTOM_MATERIAL: HandleUntyped =
46 | HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 8213474567257890329);
47 |
48 | impl Plugin for Core2dCustomPlugin {
49 | fn build(&self, app: &mut App) {
50 | let mut assets = app.world.resource_mut::>();
51 | assets.set_untracked(
52 | CUSTOM_DEFAULT_VERT,
53 | Shader::from_glsl(include_str!("shaders/default.vert"), ShaderStage::Vertex),
54 | );
55 | assets.set_untracked(
56 | CUSTOM_UPSCALING,
57 | Shader::from_glsl(
58 | include_str!("shaders/upscaling.frag"),
59 | ShaderStage::Fragment,
60 | ),
61 | );
62 | assets.set_untracked(
63 | CUSTOM_DOWNSCALING,
64 | Shader::from_glsl(
65 | include_str!("shaders/downscaling.frag"),
66 | ShaderStage::Fragment,
67 | ),
68 | );
69 | assets.set_untracked(
70 | CUSTOM_TONEMAPPING,
71 | Shader::from_glsl(
72 | include_str!("shaders/tonemapping.frag"),
73 | ShaderStage::Fragment,
74 | ),
75 | );
76 | assets.set_untracked(
77 | CUSTOM_MATERIAL,
78 | Shader::from_wgsl(include_str!("shaders/color_material_custom.wgsl")),
79 | );
80 |
81 | app.add_plugin(ColorMaterialCustomPlugin);
82 |
83 | app.insert_resource(AmbientLight { color: bevy::prelude::Color::WHITE * 30.0 });
84 |
85 | app.add_system_to_stage(
86 | CoreStage::Last,
87 | update_lights,
88 | );
89 |
90 | let render_app = match app.get_sub_app_mut(RenderApp) {
91 | Ok(render_app) => render_app,
92 | Err(_) => return,
93 | };
94 |
95 | render_app.init_resource::();
96 | render_app.init_resource::();
97 |
98 | render_app.add_system_to_stage(
99 | RenderStage::Prepare,
100 | prepare_view_targets_custom.after(WindowSystem::Prepare),
101 | );
102 |
103 | render_app.add_system_to_stage(
104 | RenderStage::Prepare,
105 | prepare_bloom_targets.after(WindowSystem::Prepare),
106 | );
107 |
108 | render_app.insert_resource(UniformBuffer::::default());
109 |
110 | let pass_node_2d = MainPass2dNodeCustom::new(&mut render_app.world);
111 | let bloom_node = BloomNode::new(&mut render_app.world);
112 | let tone_mapping_node = ToneMappingNode::new(&mut render_app.world);
113 |
114 | let mut graph = render_app.world.resource_mut::();
115 | let draw_2d_graph = graph
116 | .get_sub_graph_mut(bevy::core_pipeline::core_2d::graph::NAME)
117 | .unwrap();
118 |
119 | draw_2d_graph.remove_node(graph::node::MAIN_PASS).unwrap();
120 |
121 | draw_2d_graph.add_node(graph::node::MAIN_PASS, pass_node_2d);
122 | draw_2d_graph.add_node(BloomNode::NAME, bloom_node);
123 | draw_2d_graph.add_node(ToneMappingNode::NAME, tone_mapping_node);
124 |
125 | draw_2d_graph
126 | .add_slot_edge(
127 | draw_2d_graph.input_node().unwrap().id,
128 | graph::input::VIEW_ENTITY,
129 | graph::node::MAIN_PASS,
130 | MainPass2dNode::IN_VIEW,
131 | )
132 | .unwrap();
133 |
134 | draw_2d_graph
135 | .add_slot_edge(
136 | draw_2d_graph.input_node().unwrap().id,
137 | graph::input::VIEW_ENTITY,
138 | ToneMappingNode::NAME,
139 | ToneMappingNode::IN_VIEW,
140 | )
141 | .unwrap();
142 |
143 | draw_2d_graph
144 | .add_slot_edge(
145 | draw_2d_graph.input_node().unwrap().id,
146 | graph::input::VIEW_ENTITY,
147 | BloomNode::NAME,
148 | BloomNode::IN_VIEW,
149 | )
150 | .unwrap();
151 |
152 | draw_2d_graph
153 | .add_slot_edge(
154 | graph::node::MAIN_PASS,
155 | MainPass2dNodeCustom::OUT_TEXTURE,
156 | BloomNode::NAME,
157 | BloomNode::IN_TEXTURE,
158 | )
159 | .unwrap();
160 |
161 | draw_2d_graph
162 | .add_slot_edge(
163 | BloomNode::NAME,
164 | BloomNode::OUT_TEXTURE,
165 | ToneMappingNode::NAME,
166 | ToneMappingNode::IN_TEXTURE,
167 | )
168 | .unwrap();
169 |
170 | draw_2d_graph
171 | .add_node_edge(ToneMappingNode::NAME, draw_ui_graph::node::UI_PASS)
172 | .unwrap();
173 | }
174 | }
175 |
176 | #[derive(Component)]
177 | pub struct ViewTargetCustom {
178 | pub view: TextureView,
179 | pub sampled_target: Option,
180 | }
181 |
182 | impl ViewTargetCustom {
183 | pub fn get_color_attachment(&self, ops: Operations) -> RenderPassColorAttachment {
184 | RenderPassColorAttachment {
185 | view: self.sampled_target.as_ref().unwrap_or(&self.view),
186 | resolve_target: if self.sampled_target.is_some() {
187 | Some(&self.view)
188 | } else {
189 | None
190 | },
191 | ops,
192 | }
193 | }
194 |
195 | pub fn get_texture_view(&self) -> TextureView {
196 | self.view.clone()
197 | }
198 | }
199 |
200 | fn prepare_view_targets_custom(
201 | mut commands: Commands,
202 | msaa: Res,
203 | render_device: Res,
204 | mut texture_cache: ResMut,
205 | cameras: Query<(Entity, &ExtractedCamera)>,
206 | ) {
207 | let mut sampled_textures = HashMap::default();
208 | let mut textures = HashMap::default();
209 |
210 | for (entity, camera) in &cameras {
211 | if let Some(target_size) = camera.physical_target_size {
212 | let texture_view = textures
213 | .entry(camera.target.clone())
214 | .or_insert_with(|| {
215 | texture_cache.get(
216 | &render_device,
217 | TextureDescriptor {
218 | label: Some("color_attachment_texture_custom"),
219 | size: Extent3d {
220 | width: target_size.x,
221 | height: target_size.y,
222 | depth_or_array_layers: 1,
223 | },
224 | mip_level_count: 1,
225 | sample_count: 1,
226 | dimension: TextureDimension::D2,
227 | format: TextureFormat::Rg11b10Float,
228 | usage: TextureUsages::RENDER_ATTACHMENT
229 | | TextureUsages::TEXTURE_BINDING,
230 | },
231 | )
232 | })
233 | .default_view
234 | .clone();
235 |
236 | let sampled_target = if msaa.samples > 1 {
237 | let sampled_texture = sampled_textures
238 | .entry(camera.target.clone())
239 | .or_insert_with(|| {
240 | texture_cache.get(
241 | &render_device,
242 | TextureDescriptor {
243 | label: Some("sampled_color_attachment_texture_custom"),
244 | size: Extent3d {
245 | width: target_size.x,
246 | height: target_size.y,
247 | depth_or_array_layers: 1,
248 | },
249 | mip_level_count: 1,
250 | sample_count: msaa.samples,
251 | dimension: TextureDimension::D2,
252 | format: TextureFormat::Rg11b10Float,
253 | usage: TextureUsages::RENDER_ATTACHMENT
254 | | TextureUsages::TEXTURE_BINDING,
255 | },
256 | )
257 | });
258 | Some(sampled_texture.default_view.clone())
259 | } else {
260 | None
261 | };
262 | commands.entity(entity).insert(ViewTargetCustom {
263 | view: texture_view.clone(),
264 | sampled_target,
265 | });
266 | }
267 | }
268 | }
269 |
--------------------------------------------------------------------------------
/post-processing/src/lights.rs:
--------------------------------------------------------------------------------
1 | use bevy::prelude::*;
2 | use bevy::render::render_resource::ShaderType;
3 |
4 | use crate::ColorMaterialCustom;
5 |
6 | #[derive(Component, Debug, Default)]
7 | pub struct PointLight2d {
8 | pub radius: f32,
9 | pub color: Color,
10 | }
11 |
12 | #[derive(Debug, Clone)]
13 | pub struct AmbientLight {
14 | pub color: Color,
15 | }
16 |
17 | #[derive(ShaderType, Clone, Debug)]
18 | pub struct PointLightsUniform {
19 | pub lights_num: u32,
20 | pub positions: [Vec4; 16],
21 | pub colors: [Vec4; 16],
22 | pub ambient: Vec4,
23 | }
24 |
25 | impl Default for PointLightsUniform {
26 | fn default() -> Self {
27 | Self {
28 | lights_num: 0,
29 | positions: [Vec4::ZERO; 16],
30 | colors: [Vec4::ZERO; 16],
31 | ambient: Vec4::new(30.0, 30.0, 30.0, 1.0),
32 | }
33 | }
34 | }
35 |
36 | pub fn update_lights(
37 | lights_query: Query<(&PointLight2d, &GlobalTransform)>,
38 | handles: Query<&Handle>,
39 | mut materials: ResMut>,
40 | ambient: Res,
41 | ) {
42 | let v: Vec4 = ambient.color.into();
43 | if v.truncate().length() > 10.0 && !ambient.is_changed() {
44 | return;
45 | }
46 |
47 |
48 | let mut lights = PointLightsUniform::default();
49 |
50 | lights.ambient = ambient.color.as_linear_rgba_f32().into();
51 |
52 | for (point_light, transform) in lights_query.iter() {
53 | if point_light.radius < 0.01 {
54 | continue;
55 | }
56 |
57 | let i = lights.lights_num as usize;
58 | lights.positions[i] = Vec4::new(transform.translation().x, transform.translation().y, transform.translation().z, point_light.radius);
59 | lights.colors[i] = point_light.color.as_linear_rgba_f32().into();
60 | lights.lights_num += 1;
61 | }
62 |
63 | for handle in handles.iter() {
64 | if let Some(material) = materials.get_mut(handle) {
65 | material.lights = lights.clone();
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/post-processing/src/main_pass_2d_node.rs:
--------------------------------------------------------------------------------
1 | use bevy::core_pipeline::clear_color::ClearColorConfig;
2 | use bevy::core_pipeline::core_2d::{Transparent2d};
3 | use bevy::prelude::*;
4 | use bevy::render::camera::ExtractedCamera;
5 | use bevy::render::render_graph::{
6 | Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType,
7 | };
8 | use bevy::render::render_phase::{DrawFunctions, RenderPhase, TrackedRenderPass};
9 | use bevy::render::renderer::RenderContext;
10 | use bevy::render::view::{ExtractedView};
11 |
12 | use wgpu::{LoadOp, Operations, RenderPassDescriptor};
13 |
14 | use crate::ViewTargetCustom;
15 |
16 | pub struct MainPass2dNodeCustom {
17 | query: QueryState<
18 | (
19 | &'static ExtractedCamera,
20 | &'static RenderPhase,
21 | &'static ViewTargetCustom,
22 | &'static Camera2d,
23 | ),
24 | With,
25 | >,
26 | }
27 |
28 | impl MainPass2dNodeCustom {
29 | pub const IN_VIEW: &'static str = "view";
30 | pub const OUT_TEXTURE: &'static str = "texture";
31 |
32 | pub fn new(world: &mut World) -> Self {
33 | Self {
34 | query: world.query_filtered(),
35 | }
36 | }
37 | }
38 |
39 | impl Node for MainPass2dNodeCustom {
40 | fn input(&self) -> Vec {
41 | vec![SlotInfo::new(
42 | MainPass2dNodeCustom::IN_VIEW,
43 | SlotType::Entity,
44 | )]
45 | }
46 |
47 | fn output(&self) -> Vec {
48 | vec![SlotInfo::new(
49 | MainPass2dNodeCustom::OUT_TEXTURE,
50 | SlotType::TextureView,
51 | )]
52 | }
53 |
54 | fn update(&mut self, world: &mut World) {
55 | self.query.update_archetypes(world);
56 | }
57 |
58 | fn run(
59 | &self,
60 | graph: &mut RenderGraphContext,
61 | render_context: &mut RenderContext,
62 | world: &World,
63 | ) -> Result<(), NodeRunError> {
64 | let view_entity = graph.get_input_entity(Self::IN_VIEW)?;
65 |
66 | if let Ok((camera, transparent_phase, target_custom, camera_2d)) =
67 | self.query.get_manual(world, view_entity)
68 | {
69 | let pass_descriptor = RenderPassDescriptor {
70 | label: Some("main_pass_2d_custom"),
71 | color_attachments: &[Some(target_custom.get_color_attachment(Operations {
72 | load: match camera_2d.clear_color {
73 | ClearColorConfig::Default => {
74 | LoadOp::Clear(world.resource::().0.into())
75 | }
76 | ClearColorConfig::Custom(color) => LoadOp::Clear(color.into()),
77 | ClearColorConfig::None => LoadOp::Load,
78 | },
79 | store: true,
80 | }))],
81 | depth_stencil_attachment: None,
82 | };
83 |
84 | let draw_functions = world.resource::>();
85 |
86 | let render_pass = render_context
87 | .command_encoder
88 | .begin_render_pass(&pass_descriptor);
89 |
90 | let mut draw_functions = draw_functions.write();
91 | let mut tracked_pass = TrackedRenderPass::new(render_pass);
92 | if let Some(viewport) = camera.viewport.as_ref() {
93 | tracked_pass.set_camera_viewport(viewport);
94 | }
95 | for item in &transparent_phase.items {
96 | let draw_function = draw_functions.get_mut(item.draw_function).unwrap();
97 | draw_function.draw(world, &mut tracked_pass, view_entity, item);
98 | }
99 |
100 | graph
101 | .set_output(
102 | MainPass2dNodeCustom::OUT_TEXTURE,
103 | target_custom.get_texture_view(),
104 | )
105 | .unwrap();
106 | }
107 |
108 | Ok(())
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/post-processing/src/shaders/color_material_custom.wgsl:
--------------------------------------------------------------------------------
1 | #import bevy_sprite::mesh2d_types
2 | #import bevy_sprite::mesh2d_view_bindings
3 |
4 |
5 | let MAX_LIGHTS_NUM: i32 = 16;
6 |
7 | struct Lights {
8 | lights_num: u32,
9 | positions: array, MAX_LIGHTS_NUM>,
10 | colors: array, MAX_LIGHTS_NUM>,
11 | ambient: vec4,
12 | }
13 |
14 | struct ColorMaterial {
15 | color: vec4,
16 | // 'flags' is a bit field indicating various options. u32 is 32 bits so we have up to 32 options.
17 | flags: u32,
18 | lights: Lights,
19 | };
20 |
21 | let COLOR_MATERIAL_FLAGS_TEXTURE_BIT: u32 = 1u;
22 | let COLOR_MATERIAL_FLAGS_EMISSIVE_BIT: u32 = 2u;
23 | let COLOR_MATERIAL_FLAGS_OVERLAY_BIT: u32 = 4u;
24 |
25 | @group(1) @binding(0)
26 | var material: ColorMaterial;
27 | @group(1) @binding(1)
28 | var texture: texture_2d;
29 | @group(1) @binding(2)
30 | var texture_sampler: sampler;
31 | @group(1) @binding(3)
32 | var emissive: texture_2d;
33 | @group(1) @binding(4)
34 | var emissive_sampler: sampler;
35 | @group(1) @binding(5)
36 | var overlay: texture_2d;
37 | @group(1) @binding(6)
38 | var overlay_sampler: sampler;
39 |
40 | @group(2) @binding(0)
41 | var mesh: Mesh2d;
42 |
43 | struct FragmentInput {
44 | @builtin(front_facing) is_front: bool,
45 | #import bevy_sprite::mesh2d_vertex_output
46 | };
47 |
48 | fn hsl2rgb(c: vec3) -> vec3
49 | {
50 | var x = c.x*6.0+vec3(0.0,4.0,2.0);
51 | var d = vec3(x.x % 6.0,x.y % 6.0,x.z % 6.0);
52 | var rgb = clamp(abs(d - 3.0) - 1.0, vec3(0.0), vec3(1.0));
53 | return c.z + c.y * (rgb - 0.5)*(1.0 - abs(2.0*c.z - 1.0));
54 | }
55 |
56 | @fragment
57 | fn fragment(in: FragmentInput) -> @location(0) vec4 {
58 | var output_color: vec4 = material.color;
59 | if ((material.flags & COLOR_MATERIAL_FLAGS_TEXTURE_BIT) != 0u) {
60 | var texture_color = textureSample(texture, texture_sampler, in.uv);
61 | if ((material.flags & COLOR_MATERIAL_FLAGS_EMISSIVE_BIT) != 0u) {
62 | let emissive = textureSample(emissive, emissive_sampler, in.uv);
63 | texture_color = texture_color + vec4(emissive.rgb * emissive.a, 0.0) * 5.0;
64 | }
65 | #ifdef VERTEX_COLORS
66 | output_color = output_color * texture_color * in.color;
67 | #else
68 | output_color = output_color * texture_color;
69 | #endif
70 | if ((material.flags & COLOR_MATERIAL_FLAGS_OVERLAY_BIT) != 0u) {
71 | let overlay = textureSample(overlay, overlay_sampler, in.uv);
72 | output_color = vec4(output_color.rgb * (1.0 - overlay.w) + overlay.rgb * overlay.w, output_color.w);
73 | }
74 | }
75 |
76 | if (output_color.a < 0.01) {
77 | output_color = vec4(output_color.rgb, 0.0);
78 | }
79 |
80 | var light = material.lights.ambient.rgb;
81 |
82 | for (var i:u32 = 0u; i < material.lights.lights_num; i++) {
83 | let radius = material.lights.positions[i].w;
84 | let dist = length(in.world_position.xy - material.lights.positions[i].xy);
85 | if (dist >= radius) {
86 | // continue;
87 | }
88 | //let intensity = sqrt(1.0 - dist * dist / (radius * radius));
89 | let x = dist / radius;
90 | let intensity = exp(-x*x*4.0);
91 | light += intensity * material.lights.colors[i].rgb;
92 | }
93 |
94 | light = light / (1.0 + dot(light, vec3(0.33, 0.33, 0.33)));
95 |
96 | output_color = vec4(output_color.rgb * light, output_color.w);
97 |
98 | return output_color;
99 | }
100 |
--------------------------------------------------------------------------------
/post-processing/src/shaders/default.vert:
--------------------------------------------------------------------------------
1 | #version 450
2 |
3 | layout (location = 0) in vec3 vertex;
4 | layout (location = 0) out vec3 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vertex.xy * 2 - 1, vertex.z, 1.0);
8 | uv = vec3(vertex.x, 1 - vertex.y, vertex.z);
9 | }
10 |
--------------------------------------------------------------------------------
/post-processing/src/shaders/downscaling.frag:
--------------------------------------------------------------------------------
1 | #version 450
2 |
3 | layout (location = 0) in vec3 uv;
4 | layout (location = 0) out vec4 out_color;
5 |
6 | #ifdef MSAA
7 | #define TEXTURE texture2DMS
8 | #define SAMPLER sampler2DMS
9 | #else
10 | #define TEXTURE texture2D
11 | #define SAMPLER sampler2D
12 | #endif
13 |
14 | layout(binding = 0) uniform sampler default_sampler;
15 | layout(binding = 1) uniform TEXTURE color_texture;
16 | layout(binding = 3) uniform uvec4 step;
17 |
18 | vec4 quadratic_threshold(vec4 color, float threshold, vec3 curve) {
19 | float br = max(max(color.r, color.g), color.b);
20 |
21 | float rq = clamp(br - curve.x, 0.0, curve.y);
22 | rq = curve.z * rq * rq;
23 |
24 | return color * max(rq, br - threshold) / max(br, 0.0001);
25 | }
26 |
27 | vec4 sample_13(vec2 scale) {
28 | vec4 a = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2(-1.0, -1.0) * scale);
29 | vec4 b = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2( 0.0, -1.0) * scale);
30 | vec4 c = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2( 1.0, -1.0) * scale);
31 | vec4 d = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2(-0.5, -0.5) * scale);
32 | vec4 e = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2( 0.5, -0.5) * scale);
33 | vec4 f = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2(-1.0, 0.0) * scale);
34 | vec4 g = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2( 0.0, 0.0) * scale);
35 | vec4 h = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2( 1.0, 0.0) * scale);
36 | vec4 i = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2(-0.5, 0.5) * scale);
37 | vec4 j = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2( 0.5, 0.5) * scale);
38 | vec4 k = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2(-1.0, 1.0) * scale);
39 | vec4 l = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2( 0.0, 1.0) * scale);
40 | vec4 m = texture(sampler2D(color_texture, default_sampler), uv.xy + vec2( 1.0, 1.0) * scale);
41 |
42 | vec4 res = (d + e + i + j) * 0.5
43 | + (a + b + g + f) * 0.125
44 | + (b + c + h + g) * 0.125
45 | + (f + g + l + k) * 0.125
46 | + (g + h + m + l) * 0.125;
47 |
48 | return res * 0.25;
49 | }
50 |
51 | void main() {
52 | ivec2 texSize = textureSize(color_texture, 0);
53 | vec2 scale = 1.0 / vec2(texSize);
54 | out_color = sample_13(scale);
55 |
56 | if (step.x == 1) {
57 | float threshold = 1.8;
58 | float knee = 0.1;
59 | vec3 curve = vec3(threshold - knee, knee * 2.0, 0.25 / knee);
60 |
61 | out_color = quadratic_threshold(out_color, threshold, curve);
62 | out_color = max(out_color, vec4(0.00001));
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/post-processing/src/shaders/tonemapping.frag:
--------------------------------------------------------------------------------
1 | #version 450
2 |
3 | layout (location = 0) in vec3 uv;
4 | layout (location = 0) out vec4 out_color;
5 |
6 | layout(binding = 0) uniform sampler default_sampler;
7 | layout(binding = 1) uniform texture2D color_texture;
8 |
9 | float gamma = 1.3;
10 |
11 | vec3 tonemapping(vec3 color) {
12 | float luma = dot(color, vec3(0.33, 0.33, 0.33));
13 | color += smoothstep(0.6, 2.5, luma) * luma * 0.5;
14 | luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
15 | color /= (0.5 + luma);
16 | color = pow(color, vec3(1. / gamma));
17 | return color;
18 | }
19 |
20 | void main() {
21 | ivec2 texSize = textureSize(color_texture, 0);
22 |
23 | vec4 color = texelFetch(sampler2D(color_texture, default_sampler), ivec2(uv.xy * texSize), 0).rgba;
24 | out_color.xyz = tonemapping(color.xyz);
25 | out_color.w = color.w;
26 | }
27 |
--------------------------------------------------------------------------------
/post-processing/src/shaders/upscaling.frag:
--------------------------------------------------------------------------------
1 | #version 450
2 |
3 | layout (location = 0) in vec3 uv;
4 | layout (location = 0) out vec4 out_color;
5 |
6 | layout(binding = 0) uniform sampler default_sampler;
7 | layout(binding = 1) uniform texture2D first_texture; // smaller
8 | layout(binding = 2) uniform texture2D second_texture; // bigger
9 | layout(binding = 3) uniform uvec4 step;
10 |
11 | vec4 sample_tent(vec2 scale) {
12 | vec4 d = vec4(1.0, 1.0, -1.0, 0.0);
13 |
14 | vec4 s = texture(sampler2D(first_texture, default_sampler), uv.xy - d.xy * scale)
15 | + texture(sampler2D(first_texture, default_sampler), uv.xy - d.wy * scale) * 2.0
16 | + texture(sampler2D(first_texture, default_sampler), uv.xy - d.zy * scale)
17 | + texture(sampler2D(first_texture, default_sampler), uv.xy + d.zw * scale) * 2.0
18 | + texture(sampler2D(first_texture, default_sampler), uv.xy ) * 4.0
19 | + texture(sampler2D(first_texture, default_sampler), uv.xy + d.xw * scale) * 2.0
20 | + texture(sampler2D(first_texture, default_sampler), uv.xy + d.zy * scale)
21 | + texture(sampler2D(first_texture, default_sampler), uv.xy + d.wy * scale) * 2.0
22 | + texture(sampler2D(first_texture, default_sampler), uv.xy + d.xy * scale);
23 |
24 | return s / 16.0;
25 | }
26 |
27 | void main() {
28 | ivec2 texSize = textureSize(first_texture, 0);
29 | vec2 scale = 1.0 / vec2(texSize);
30 |
31 | vec4 up_sample = sample_tent(scale * 1.0);
32 | vec4 color = texture(sampler2D(second_texture, default_sampler), uv.xy);
33 |
34 | if (step.x == 1) {
35 | out_color = vec4(color.rgb * 1.0 + up_sample.rgb * 0.6, 1.0);
36 | } else {
37 | out_color = vec4(color.rgb + up_sample.rgb * 0.3, 1.0);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/post-processing/src/tone_mapping_node.rs:
--------------------------------------------------------------------------------
1 | use bevy::prelude::*;
2 | use bevy::render::camera::ExtractedCamera;
3 | use bevy::render::mesh::PrimitiveTopology;
4 | use bevy::render::render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType};
5 | use bevy::render::render_phase::TrackedRenderPass;
6 | use bevy::render::render_resource::{
7 | BindGroupLayout, BindGroupLayoutEntry, BindingType, BlendState, BufferVec,
8 | CachedRenderPipelineId, ColorTargetState, ColorWrites, FragmentState, FrontFace,
9 | MultisampleState, PipelineCache, PolygonMode, PrimitiveState, RenderPipelineDescriptor,
10 | Sampler, SamplerBindingType, ShaderStages, TextureFormat, TextureSampleType,
11 | TextureViewDimension, VertexBufferLayout, VertexFormat, VertexState, VertexStepMode,
12 | };
13 | use bevy::render::renderer::{RenderContext, RenderDevice, RenderQueue};
14 | use bevy::render::texture::BevyDefault;
15 | use bevy::render::view::{ExtractedView, ViewTarget};
16 | use wgpu::{
17 | BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor, BindingResource,
18 | Operations, RenderPassColorAttachment, RenderPassDescriptor,
19 | };
20 |
21 | use crate::CUSTOM_DEFAULT_VERT;
22 | use crate::CUSTOM_TONEMAPPING;
23 | use crate::utils::{create_default_quad, create_default_sampler, ScreenVertex};
24 |
25 | pub struct ToneMappingNode {
26 | query: QueryState<
27 | (
28 | &'static ExtractedCamera,
29 | &'static ViewTarget,
30 | &'static Camera2d,
31 | ),
32 | With,
33 | >,
34 | screen_quad: BufferVec,
35 | sampler: Sampler,
36 | }
37 |
38 | impl ToneMappingNode {
39 | pub const NAME: &'static str = "tone_mapping";
40 | pub const IN_VIEW: &'static str = "view";
41 | pub const IN_TEXTURE: &'static str = "tone_mapping_in_texture";
42 |
43 | pub fn new(world: &mut World) -> Self {
44 | let query = world.query_filtered();
45 | let render_device = world.resource::();
46 | let render_queue = world.resource::();
47 |
48 | Self {
49 | query,
50 | sampler: create_default_sampler(render_device),
51 | screen_quad: create_default_quad(render_device, render_queue),
52 | }
53 | }
54 | }
55 |
56 | impl Node for ToneMappingNode {
57 | fn input(&self) -> Vec {
58 | vec![
59 | SlotInfo::new(ToneMappingNode::IN_VIEW, SlotType::Entity),
60 | SlotInfo::new(ToneMappingNode::IN_TEXTURE, SlotType::TextureView),
61 | ]
62 | }
63 |
64 | fn update(&mut self, world: &mut World) {
65 | self.query.update_archetypes(world);
66 | }
67 |
68 | fn run(
69 | &self,
70 | graph: &mut RenderGraphContext,
71 | render_context: &mut RenderContext,
72 | world: &World,
73 | ) -> Result<(), NodeRunError> {
74 | let view_entity = graph.get_input_entity(Self::IN_VIEW)?;
75 | let input = graph.get_input_texture(Self::IN_TEXTURE)?;
76 |
77 | let (camera, target, _camera_2d) =
78 | if let Ok(result) = self.query.get_manual(world, view_entity) {
79 | result
80 | } else {
81 | return Ok(());
82 | };
83 | let pass_descriptor = RenderPassDescriptor {
84 | label: Some("tone_mapping_pass"),
85 | color_attachments: &[Some(RenderPassColorAttachment {
86 | view: &target.view,
87 | resolve_target: None,
88 | ops: Operations::default(),
89 | })],
90 | depth_stencil_attachment: None,
91 | };
92 |
93 | let render_pass = render_context
94 | .command_encoder
95 | .begin_render_pass(&pass_descriptor);
96 |
97 | let render_device = world.resource::();
98 | let pipeline_cache = world.resource::();
99 | let pipeline = world.resource::();
100 |
101 | let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
102 | label: Some("final_pass_bind_group"),
103 | layout: &pipeline.layout,
104 | entries: &[
105 | BindGroupEntry {
106 | binding: 0,
107 | resource: BindingResource::Sampler(&self.sampler),
108 | },
109 | BindGroupEntry {
110 | binding: 1,
111 | resource: BindingResource::TextureView(input),
112 | },
113 | ],
114 | });
115 |
116 | if let Some(pipeline) = pipeline_cache.get_render_pipeline(pipeline.pipeline) {
117 | let mut tracked_pass = TrackedRenderPass::new(render_pass);
118 | if let Some(viewport) = camera.viewport.as_ref() {
119 | tracked_pass.set_camera_viewport(viewport);
120 | }
121 | tracked_pass.set_render_pipeline(pipeline);
122 | tracked_pass.set_bind_group(0, &bind_group, &[]);
123 | tracked_pass.set_vertex_buffer(0, self.screen_quad.buffer().unwrap().slice(..));
124 | tracked_pass.draw(0..self.screen_quad.len() as u32, 0..1);
125 | }
126 |
127 | Ok(())
128 | }
129 | }
130 |
131 | #[derive(Clone)]
132 | pub struct ToneMappingPipeline {
133 | pub layout: BindGroupLayout,
134 | pub pipeline: CachedRenderPipelineId,
135 | }
136 |
137 | impl FromWorld for ToneMappingPipeline {
138 | fn from_world(world: &mut World) -> Self {
139 | let render_device = world.resource::().clone();
140 | let layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
141 | label: Some("tone_mapping_layout"),
142 | entries: &[
143 | BindGroupLayoutEntry {
144 | binding: 0,
145 | visibility: ShaderStages::FRAGMENT,
146 | ty: BindingType::Sampler(SamplerBindingType::NonFiltering),
147 | count: None,
148 | },
149 | BindGroupLayoutEntry {
150 | binding: 1,
151 | visibility: ShaderStages::FRAGMENT,
152 | ty: BindingType::Texture {
153 | multisampled: false,
154 | view_dimension: TextureViewDimension::D2,
155 | sample_type: TextureSampleType::Float { filterable: false },
156 | },
157 | count: None,
158 | },
159 | ],
160 | });
161 |
162 | let mut pipeline_cache = world.resource_mut::();
163 |
164 | let pipeline = pipeline_cache.queue_render_pipeline(RenderPipelineDescriptor {
165 | label: Some("tone_mapping_pass".into()),
166 | vertex: VertexState {
167 | shader: CUSTOM_DEFAULT_VERT.typed(),
168 | entry_point: "main".into(),
169 | shader_defs: vec![],
170 | buffers: vec![VertexBufferLayout::from_vertex_formats(
171 | VertexStepMode::Vertex,
172 | vec![VertexFormat::Float32x3],
173 | )],
174 | },
175 | fragment: Some(FragmentState {
176 | shader: CUSTOM_TONEMAPPING.typed(),
177 | shader_defs: vec![],
178 | entry_point: "main".into(),
179 | targets: vec![Some(ColorTargetState {
180 | format: TextureFormat::bevy_default(),
181 | blend: Some(BlendState::ALPHA_BLENDING),
182 | write_mask: ColorWrites::ALL,
183 | })],
184 | }),
185 | layout: Some(vec![layout.clone()]),
186 | primitive: PrimitiveState {
187 | front_face: FrontFace::Ccw,
188 | cull_mode: None,
189 | unclipped_depth: false,
190 | polygon_mode: PolygonMode::Fill,
191 | conservative: false,
192 | topology: PrimitiveTopology::TriangleList,
193 | strip_index_format: None,
194 | },
195 | depth_stencil: None,
196 | multisample: MultisampleState {
197 | count: 1,
198 | mask: !0,
199 | alpha_to_coverage_enabled: false,
200 | },
201 | });
202 |
203 | Self { layout, pipeline }
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/post-processing/src/utils.rs:
--------------------------------------------------------------------------------
1 | use bevy::core::{Pod, Zeroable};
2 | use bevy::render::render_resource::{BufferUsages, BufferVec, FilterMode, Sampler};
3 | use bevy::render::renderer::{RenderDevice, RenderQueue};
4 | use wgpu::{AddressMode, SamplerDescriptor};
5 |
6 | #[repr(C)]
7 | #[derive(Copy, Clone, Pod, Zeroable)]
8 | pub struct ScreenVertex {
9 | pub position: [f32; 3],
10 | }
11 |
12 | pub fn create_default_quad(
13 | render_device: &RenderDevice,
14 | render_queue: &RenderQueue,
15 | ) -> BufferVec {
16 | let mut screen_quad = BufferVec::new(BufferUsages::VERTEX);
17 | // Triangle 1
18 | screen_quad.push(ScreenVertex {
19 | position: [0.0, 0.0, 0.0],
20 | });
21 | screen_quad.push(ScreenVertex {
22 | position: [0.0, 1.0, 0.0],
23 | });
24 | screen_quad.push(ScreenVertex {
25 | position: [1.0, 1.0, 0.0],
26 | });
27 | // Triangle 2
28 | screen_quad.push(ScreenVertex {
29 | position: [0.0, 0.0, 0.0],
30 | });
31 | screen_quad.push(ScreenVertex {
32 | position: [1.0, 0.0, 0.0],
33 | });
34 | screen_quad.push(ScreenVertex {
35 | position: [1.0, 1.0, 0.0],
36 | });
37 | screen_quad.write_buffer(render_device, render_queue);
38 | return screen_quad;
39 | }
40 |
41 | pub fn create_default_sampler(render_device: &RenderDevice) -> Sampler {
42 | render_device.create_sampler(&SamplerDescriptor {
43 | label: Some("default_sampler"),
44 | mag_filter: FilterMode::Nearest,
45 | min_filter: FilterMode::Nearest,
46 | address_mode_u: AddressMode::ClampToEdge,
47 | address_mode_v: AddressMode::ClampToEdge,
48 | address_mode_w: AddressMode::ClampToEdge,
49 | ..Default::default()
50 | })
51 | }
52 |
53 | pub fn create_linear_sampler(render_device: &RenderDevice) -> Sampler {
54 | render_device.create_sampler(&SamplerDescriptor {
55 | label: Some("linear_sampler"),
56 | mag_filter: FilterMode::Linear,
57 | min_filter: FilterMode::Linear,
58 | address_mode_u: AddressMode::ClampToEdge,
59 | address_mode_v: AddressMode::ClampToEdge,
60 | address_mode_w: AddressMode::ClampToEdge,
61 | ..Default::default()
62 | })
63 | }
64 |
--------------------------------------------------------------------------------
/src/core/audio.rs:
--------------------------------------------------------------------------------
1 | use std::{path::PathBuf, time::Duration};
2 |
3 | use bevy::{
4 | prelude::{
5 | App, AssetServer, Assets, Commands, Entity, Handle, Local, Plugin, Query, Res, ResMut, SystemSet,
6 | },
7 | utils::{HashMap, Instant},
8 | };
9 | use bevy_kira_audio::{Audio, AudioControl, AudioEasing, AudioInstance, AudioTween};
10 |
11 | use crate::states::AudioState;
12 |
13 | use super::Player;
14 |
15 | pub struct BackgroundMusicHandle(Handle);
16 |
17 | #[derive(Clone, PartialEq, Eq, Debug, Hash)]
18 | pub struct BackgroundMusic(pub Option);
19 |
20 | #[derive(Debug)]
21 | pub struct PlayerStatus {
22 | handle: Handle,
23 | start_time: Option,
24 | }
25 |
26 | pub struct AudioPlugin;
27 |
28 | impl Plugin for AudioPlugin {
29 | fn build(&self, app: &mut App) {
30 | app.add_system_set(SystemSet::on_enter(AudioState::Menu).with_system(setup_menu_music));
31 | app.add_system(play_background_music);
32 | app.add_system(play_player_movement_sound);
33 |
34 | app.insert_resource(BackgroundMusic(Some(
35 | "audio/main_menu_background.ogg".to_string(),
36 | )));
37 | }
38 | }
39 |
40 | fn setup_menu_music(mut background_music: ResMut) {
41 | background_music.0 = Some("audio/main_menu_background.ogg".to_string());
42 | }
43 |
44 | fn play_background_music(
45 | mut commands: Commands,
46 | audio: Res