From 369cac3c3245214ebf9d03e33e98fb68acb96c10 Mon Sep 17 00:00:00 2001 From: Silas Bartha Date: Mon, 3 Jun 2024 21:10:39 -0400 Subject: Renamed + Added docs --- .github/workflows/docs.yml | 50 +++++++++++++++++++++++++++++++++ .github/workflows/rust.yml | 24 ++++++++++++++++ Cargo.toml | 4 +-- README.md | 14 ++++----- assets/shaders/dither_post_process.wgsl | 10 +++---- src/components.rs | 22 ++++++++------- src/lib.rs | 49 +++++++++++++++++++++----------- src/nodes.rs | 21 ++++++++++++-- src/resources.rs | 2 +- 9 files changed, 153 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/docs.yml create mode 100644 .github/workflows/rust.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..3191cc0 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,50 @@ +name: Docs +on: + push: + branches: [master] +permissions: + contents: read + pages: write + id-token: write +concurrency: + group: deploy + cancel-in-progress: false +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install Dependencies + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + - name: Configure cache + uses: Swatinem/rust-cache@v2 + - name: Setup pages + id: pages + uses: actions/configure-pages@v4 + - name: Clean docs folder + run: cargo clean --doc + - name: Build docs + run: cargo doc --no-deps + - name: Add redirect + run: echo '' > target/doc/index.html + - name: Remove lock file + run: rm target/doc/.lock + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: target/doc + deploy: + name: Deploy + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..e38739d --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,24 @@ +name: Rust + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Install Dependencies + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --verbose diff --git a/Cargo.toml b/Cargo.toml index 924a327..fc8aeb8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "grex_dither_post_process" -version = "0.1.3" +name = "bevy_dither_post_process" +version = "0.1.4" edition = "2021" [dependencies.bevy] diff --git a/README.md b/README.md index 8633dff..04e957e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# grex_dither_post_process +# bevy_dither_post_process A plugin for the [Bevy](https://bevyengine.org) engine which adds a dither post-processing effect. @@ -10,7 +10,7 @@ The effect is implemented as a bilevel ordered dither using a Bayer matrix with ![](./doc/screenshot_plant.png) Configuration Used: ```rs -grex_dither_post_process::components::DitherPostProcessSettings::new(3, &asset_server); +bevy_dither_post_process::components::DitherPostProcessSettings::new(3, &asset_server); ``` ## Compatibility @@ -22,8 +22,8 @@ grex_dither_post_process::components::DitherPostProcessSettings::new(3, &asset_s ### Using git URL in Cargo.toml ```toml -[dependencies.grex_dither_post_process] -git = "https://github.com/exvacuum/grex_dither_post_process.git" +[dependencies.bevy_dither_post_process] +git = "https://github.com/exvacuum/bevy_dither_post_process.git" ``` ## Usage @@ -31,13 +31,13 @@ git = "https://github.com/exvacuum/grex_dither_post_process.git" In `main.rs`: ```rs use bevy::prelude::*; -use grex_dither_post_process; +use bevy_dither_post_process; fn main() { App::new() .add_plugins(( DefaultPlugins, - grex_dither_post_process::DitherPostProcessPlugin, + bevy_dither_post_process::DitherPostProcessPlugin, )) .run(); } @@ -47,7 +47,7 @@ When spawning a camera: ```rs commands.spawn(( // Camera3dBundle... - grex_dither_post_process::components::DitherPostProcessSettings::new(level, &asset_server); + bevy_dither_post_process::components::DitherPostProcessSettings::new(level, &asset_server); )); ``` diff --git a/assets/shaders/dither_post_process.wgsl b/assets/shaders/dither_post_process.wgsl index 37c25fc..6440d0d 100644 --- a/assets/shaders/dither_post_process.wgsl +++ b/assets/shaders/dither_post_process.wgsl @@ -9,16 +9,16 @@ fn fragment( in: FullscreenVertexOutput ) -> @location(0) vec4 { - let screen_size = vec2f(textureDimensions(screen_texture)); - let threshold_map_size = vec2f(textureDimensions(threshold_map_texture)); - let pixel_position = floor(in.uv * screen_size); - let map_position = (pixel_position % threshold_map_size) / threshold_map_size; + let screen_size = vec2i(textureDimensions(screen_texture)); + let threshold_map_size = vec2i(textureDimensions(threshold_map_texture)); + let pixel_position = vec2i(floor(in.uv * vec2f(screen_size))); + let map_position = vec2f(pixel_position % threshold_map_size) / vec2f(threshold_map_size); let threshold = textureSample(threshold_map_texture, threshold_map_sampler, map_position).r; let base_color = textureSample(screen_texture, screen_sampler, in.uv); let luma = (0.2126 * base_color.r + 0.7152 * base_color.g + 0.0722 * base_color.b); - let value = f32(luma > threshold); + let value = f32(luma >= threshold); return vec4f(value, value, value, 1.0); } diff --git a/src/components.rs b/src/components.rs index d22524c..1768448 100644 --- a/src/components.rs +++ b/src/components.rs @@ -1,19 +1,21 @@ use bevy::{ prelude::*, render::{ + extract_component::ExtractComponent, render_asset::RenderAssetUsages, - render_resource::{Extent3d, TextureDimension, TextureFormat, TextureUsages}, extract_component::ExtractComponent, + render_resource::{Extent3d, TextureDimension, TextureFormat, TextureUsages}, }, }; +/// Component which, when inserted into an entity with a camera, enables the dither post-processing +/// effect. #[derive(Component, ExtractComponent, Clone)] pub struct DitherPostProcessSettings(Handle); impl DitherPostProcessSettings { - pub fn new( - level: u32, - asset_server: &AssetServer, - ) -> Self { + /// Constructs a new instance ofthis component, enabling the dither effect using a bayer + /// matrix of the given level. A given level *n* will generate a square bayer matrix with a size of *(n+1)^2*. + pub fn new(level: u32, asset_server: &AssetServer) -> Self { let power = level + 1; let map_size: u32 = 1 << power; let mut buffer = Vec::::new(); @@ -38,7 +40,6 @@ impl DitherPostProcessSettings { let value = ((result as f32 / map_size.pow(2) as f32) * 255.0) as u8; buffer.push(value); } - } let mut image = Image::new( @@ -52,15 +53,16 @@ impl DitherPostProcessSettings { TextureFormat::R8Unorm, RenderAssetUsages::RENDER_WORLD, ); - image.texture_descriptor.usage = - TextureUsages::COPY_DST | TextureUsages::STORAGE_BINDING | TextureUsages::TEXTURE_BINDING; + image.texture_descriptor.usage = TextureUsages::COPY_DST + | TextureUsages::STORAGE_BINDING + | TextureUsages::TEXTURE_BINDING; let handle = asset_server.add(image); Self(handle) } - - pub fn handle(&self) -> Handle { + /// Gets the handle of the texture representing this component's Bayer matrix + pub fn handle(&self) -> Handle { self.0.clone() } } diff --git a/src/lib.rs b/src/lib.rs index 430e5d9..28eecd8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,40 +1,57 @@ -use bevy::{prelude::*, render::{RenderApp, render_graph::{RenderGraphApp, ViewNodeRunner}, extract_component::ExtractComponentPlugin}, asset::embedded_asset, core_pipeline::core_3d::graph::{Core3d, Node3d}}; +#![warn(missing_docs)] + +//! A plugin for the Bevy game engine which provides a black and white dither post-process effect +//! using Bayer ordered dithering. + +use bevy::{ + asset::embedded_asset, + core_pipeline::core_3d::graph::{Core3d, Node3d}, + prelude::*, + render::{ + extract_component::ExtractComponentPlugin, + render_graph::{RenderGraphApp, ViewNodeRunner}, + RenderApp, + }, +}; use crate::components::DitherPostProcessSettings; pub use nodes::DitherRenderLabel; +/// Plugin which provides dither post-processing functionality pub struct DitherPostProcessPlugin; +/// Components used by this plugin pub mod components; -mod resources; + mod nodes; +mod resources; impl Plugin for DitherPostProcessPlugin { fn build(&self, app: &mut App) { embedded_asset!(app, "../assets/shaders/dither_post_process.wgsl"); - app.add_plugins(( - ExtractComponentPlugin::::default(), - )); + app.add_plugins((ExtractComponentPlugin::::default(),)); let Ok(render_app) = app.get_sub_app_mut(RenderApp) else { return; }; - render_app.add_render_graph_node::>( - Core3d, - nodes::DitherRenderLabel, - ).add_render_graph_edges( - Core3d, - ( - Node3d::Tonemapping, + render_app + .add_render_graph_node::>( + Core3d, nodes::DitherRenderLabel, - Node3d::EndMainPassPostProcessing, - ), - ); + ) + .add_render_graph_edges( + Core3d, + ( + Node3d::Tonemapping, + nodes::DitherRenderLabel, + Node3d::EndMainPassPostProcessing, + ), + ); } - + fn finish(&self, app: &mut App) { let Ok(render_app) = app.get_sub_app_mut(RenderApp) else { return; diff --git a/src/nodes.rs b/src/nodes.rs index b33b2a0..377718a 100644 --- a/src/nodes.rs +++ b/src/nodes.rs @@ -1,8 +1,22 @@ -use bevy::{prelude::*, render::{render_graph::{ViewNode, NodeRunError, RenderGraphContext, RenderLabel}, view::ViewTarget, renderer::RenderContext, render_resource::{PipelineCache, BindGroupEntries, RenderPassDescriptor, RenderPassColorAttachment, Operations}, render_asset::RenderAssets}, ecs::query::QueryItem}; +use bevy::{ + ecs::query::QueryItem, + prelude::*, + render::{ + render_asset::RenderAssets, + render_graph::{NodeRunError, RenderGraphContext, RenderLabel, ViewNode}, + render_resource::{ + BindGroupEntries, Operations, PipelineCache, RenderPassColorAttachment, + RenderPassDescriptor, + }, + renderer::RenderContext, + view::ViewTarget, + }, +}; use super::components; use super::resources; +/// Label for dither post-process effect render node. #[derive(RenderLabel, Clone, Eq, PartialEq, Hash, Debug)] pub struct DitherRenderLabel; @@ -31,7 +45,10 @@ impl ViewNode for DitherRenderNode { let post_process = view_target.post_process_write(); - let Some(threshold_map) = world.resource::>().get(dither_post_process_settings.handle()) else { + let Some(threshold_map) = world + .resource::>() + .get(dither_post_process_settings.handle()) + else { warn!("Failed to get threshold map, skipping..."); return Ok(()); }; diff --git a/src/resources.rs b/src/resources.rs index d900f18..6dab3ee 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -43,7 +43,7 @@ impl FromWorld for DitherPostProcessPipeline { let threshold_map_sampler = render_device.create_sampler(&SamplerDescriptor::default()); let shader = world.resource::().load::( - "embedded://grex_dither_post_process/../assets/shaders/dither_post_process.wgsl", + "embedded://bevy_dither_post_process/../assets/shaders/dither_post_process.wgsl", ); let pipeline_id = -- cgit v1.2.3