diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components.rs | 22 | ||||
-rw-r--r-- | src/lib.rs | 49 | ||||
-rw-r--r-- | src/nodes.rs | 21 | ||||
-rw-r--r-- | src/resources.rs | 2 |
4 files changed, 65 insertions, 29 deletions
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<Image>); 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::<u8>::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<Image> { + /// Gets the handle of the texture representing this component's Bayer matrix + pub fn handle(&self) -> Handle<Image> { self.0.clone() } } @@ -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::<DitherPostProcessSettings>::default(), - )); + app.add_plugins((ExtractComponentPlugin::<DitherPostProcessSettings>::default(),)); let Ok(render_app) = app.get_sub_app_mut(RenderApp) else { return; }; - render_app.add_render_graph_node::<ViewNodeRunner<nodes::DitherRenderNode>>( - Core3d, - nodes::DitherRenderLabel, - ).add_render_graph_edges( - Core3d, - ( - Node3d::Tonemapping, + render_app + .add_render_graph_node::<ViewNodeRunner<nodes::DitherRenderNode>>( + 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::<RenderAssets<Image>>().get(dither_post_process_settings.handle()) else { + let Some(threshold_map) = world + .resource::<RenderAssets<Image>>() + .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::<AssetServer>().load::<Shader>( - "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 = |