diff --git a/src/nodes/drawable/line.wgsl b/src/nodes/drawable/line.wgsl new file mode 100644 index 0000000..a216fee --- /dev/null +++ b/src/nodes/drawable/line.wgsl @@ -0,0 +1,62 @@ +#import bevy_pbr::{ + pbr_fragment::pbr_input_from_standard_material, + pbr_functions::alpha_discard, +} + +#ifdef PREPASS_PIPELINE +#import bevy_pbr::{ + prepass_io::{VertexOutput, FragmentOutput}, + pbr_deferred_functions::deferred_output, +} +#else +#import bevy_pbr::{ + forward_io::{VertexOutput, FragmentOutput}, + pbr_functions::{apply_pbr_lighting, main_pass_post_lighting_processing}, +} +#endif + +struct MyExtendedMaterial { + quantize_steps: u32, +} + +@group(2) @binding(100) +var my_extended_material: MyExtendedMaterial; + +@fragment +fn fragment( + in: VertexOutput, + @builtin(front_facing) is_front: bool, +) -> FragmentOutput { +#ifdef VERTEX_COLORS + var out: FragmentOutput; + // apply lighting + out.color = in.color; + return out; +#endif + + // generate a PbrInput struct from the StandardMaterial bindings + var pbr_input = pbr_input_from_standard_material(in, is_front); + +#ifdef VERTEX_COLORS + // Multiply emissive color by vertex color + pbr_input.material.emissive.rgb *= in.color.rgb; +#endif + + // alpha discard + pbr_input.material.base_color = alpha_discard(pbr_input.material, pbr_input.material.base_color); + +#ifdef PREPASS_PIPELINE + // in deferred mode we can't modify anything after that, as lighting is run in a separate fullscreen shader. + let out = deferred_output(in, pbr_input); +#else + var out: FragmentOutput; + // apply lighting + out.color = apply_pbr_lighting(pbr_input); + + // apply in-shader post processing (fog, alpha-premultiply, and also tonemapping, debanding if the camera is non-hdr) + // note this does not include fullscreen postprocessing effects like bloom. + out.color = main_pass_post_lighting_processing(pbr_input, out.color); +#endif + + return out; +} diff --git a/src/nodes/drawable/lines.rs b/src/nodes/drawable/lines.rs index 2bc9545..22f4e7a 100644 --- a/src/nodes/drawable/lines.rs +++ b/src/nodes/drawable/lines.rs @@ -11,11 +11,13 @@ use crate::{ }, }; use bevy::{ - asset::RenderAssetUsages, + asset::{RenderAssetUsages, weak_handle}, + pbr::{ExtendedMaterial, MaterialExtension}, prelude::*, render::{ mesh::{Indices, MeshAabb, PrimitiveTopology}, primitives::Aabb, + render_resource::{AsBindGroup, ShaderRef}, }, }; use glam::Vec3; @@ -25,18 +27,74 @@ use std::sync::{ atomic::{AtomicBool, Ordering}, }; -pub struct LinesNodePlugin; +type LineMaterial = ExtendedMaterial; +const LINE_SHADER_HANDLE: Handle = weak_handle!("7d28aa5a-3abd-43bb-b0e9-0de8b81b650d"); +// No extra data needed for a simple holdout +#[derive(Default, Asset, AsBindGroup, TypePath, Debug, Clone)] +pub struct LineExtension { + #[uniform(100)] + unused: u32, +} +impl MaterialExtension for LineExtension { + fn fragment_shader() -> ShaderRef { + LINE_SHADER_HANDLE.into() + } -impl Plugin for LinesNodePlugin { - fn build(&self, app: &mut App) { - app.add_systems(Update, build_line_mesh); + fn prepass_fragment_shader() -> ShaderRef { + LINE_SHADER_HANDLE.into() + } + + fn alpha_mode() -> Option { + Some(AlphaMode::Opaque) } } -fn build_line_mesh( - mut meshes: ResMut>, +pub struct LinesNodePlugin; +impl Plugin for LinesNodePlugin { + fn build(&self, app: &mut App) { + app.add_systems(Startup, test_cube); + app.add_systems(Update, build_line_mesh); + app.world_mut().resource_mut::>().insert( + LINE_SHADER_HANDLE.id(), + Shader::from_wgsl( + include_str!("line.wgsl"), + std::path::Path::new(file!()) + .parent() + .unwrap() + .join("line.wgsl") + .to_string_lossy(), + ), + ); + app.add_plugins(MaterialPlugin::::default()); + } +} + +fn test_cube( mut cmds: Commands, - mut materials: ResMut>, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + cmds.spawn(( + Transform::from_xyz(0.0, 0.5, 0.0), + Mesh3d(meshes.add(Cuboid::default())), + MeshMaterial3d(materials.add(ExtendedMaterial { + base: BevyMaterial { + base_color: Color::WHITE, + perceptual_roughness: 1.0, + // TODO: this should be Blend + alpha_mode: AlphaMode::Opaque, + // emissive: Color::srgba_u8(128, 128, 128, 255).into(), + ..default() + }, + extension: LineExtension { unused: 0 }, + })), + )); +} + +fn build_line_mesh( + mut cmds: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, ) { for lines in LINES_REGISTRY .get_valid_contents() @@ -189,13 +247,16 @@ fn build_line_mesh( let e = cmds.spawn(( Name::new("LinesNode"), SpatialNode(Arc::downgrade(&lines.spatial)), - MeshMaterial3d(materials.add(BevyMaterial { - base_color: Color::WHITE, - perceptual_roughness: 1.0, - // TODO: this should be Blend - alpha_mode: AlphaMode::Opaque, - emissive: Color::srgba_u8(128, 128, 128, 255).into(), - ..default() + MeshMaterial3d(materials.add(ExtendedMaterial { + base: BevyMaterial { + base_color: Color::WHITE, + perceptual_roughness: 1.0, + // TODO: this should be Blend + alpha_mode: AlphaMode::Opaque, + // emissive: Color::srgba_u8(128, 128, 128, 255).into(), + ..default() + }, + extension: LineExtension { unused: 0 }, })), )); _ = lines.entity.set(e.id().into()); @@ -203,7 +264,6 @@ fn build_line_mesh( } }; if let Some(aabb) = mesh.compute_aabb() { - info!(?aabb); *lines.bounds.lock() = aabb; entity.insert(aabb); } diff --git a/src/wayland/dmabuf/buffer_backing.rs b/src/wayland/dmabuf/buffer_backing.rs index 0e411e2..b5ebbbe 100644 --- a/src/wayland/dmabuf/buffer_backing.rs +++ b/src/wayland/dmabuf/buffer_backing.rs @@ -82,7 +82,6 @@ impl DmabufBacking { dmatexes: &ImportedDmatexs, images: &mut Assets, ) -> Option> { - info!("updating dmabuf tex"); self.pending_imported_dmatex .lock() .take()