From 7c6edf31ccf551825afdaf0a7e40bd762b88faf1 Mon Sep 17 00:00:00 2001 From: "Elijah C. Voigt" Date: Tue, 16 Jan 2024 20:28:30 -0800 Subject: [PATCH] Saving my place w/ shader example --- assets/examples/images/texture.png | 3 + assets/examples/shaders/dissolve.wgsl | 57 ++++++++++++++++++ examples/shaders.rs | 85 +++++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 assets/examples/images/texture.png create mode 100644 assets/examples/shaders/dissolve.wgsl create mode 100644 examples/shaders.rs diff --git a/assets/examples/images/texture.png b/assets/examples/images/texture.png new file mode 100644 index 0000000..725852b --- /dev/null +++ b/assets/examples/images/texture.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbbafd145de1c0ee8643c72bda2dfd936810b5488411c34b7ce8ff49217fad08 +size 12064 diff --git a/assets/examples/shaders/dissolve.wgsl b/assets/examples/shaders/dissolve.wgsl new file mode 100644 index 0000000..d61a121 --- /dev/null +++ b/assets/examples/shaders/dissolve.wgsl @@ -0,0 +1,57 @@ +#import bevy_pbr::{ + pbr_fragment::pbr_input_from_standard_material, + forward_io::{VertexOutput, FragmentOutput}, + mesh_view_bindings::globals, + pbr_functions::{ + alpha_discard, + apply_pbr_lighting, + main_pass_post_lighting_processing + }, +} + +struct MatExt { + step: u32, +} + +@group(1) @binding(100) +var mat_ext: MatExt; + +fn random(st: vec2) -> f32 { + var a = vec2(12.9898, 78.233); + var b = 43758.5453123; + return fract(sin(dot(st.xy, a)) * b); +} + +fn noise(st: vec2) -> f32 { + var i = floor(st); + var f = floor(st); + + var a = random(i); + var b = random(i + vec2(1.0, 0.0)); + var c = random(i + vec2(0.0, 1.0)); + var d = random(i + vec2(1.0, 1.0)); + + var u = smoothstep(vec2(0.0), vec2(1.0), f); + + return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; +} + +@fragment +fn fragment( + in: VertexOutput, + @builtin(front_facing) is_front: bool, +) -> FragmentOutput { + var pbr_input = pbr_input_from_standard_material(in, is_front); + pbr_input.material.base_color.b = pbr_input.material.base_color.r; + + var out: FragmentOutput; + out.color = apply_pbr_lighting(pbr_input); + + var pos = vec2(in.uv * 5.0) + vec2(globals.time); + + var n = noise(pos); + + out.color = vec4(vec3(n), abs(sin(globals.time))); + + return out; +} \ No newline at end of file diff --git a/examples/shaders.rs b/examples/shaders.rs new file mode 100644 index 0000000..5d29f83 --- /dev/null +++ b/examples/shaders.rs @@ -0,0 +1,85 @@ +use bevy::pbr::OpaqueRendererMethod; +use bevy::prelude::*; +use bevy::pbr::ExtendedMaterial; +use bevy::pbr::MaterialExtension; +use bevy::pbr::MaterialMeshBundle; +use bevy::render::render_resource::*; + +type MyMat = ExtendedMaterial; + +fn main() { + App::new() + .add_plugins(( + DefaultPlugins.set(ImagePlugin::default_nearest()), + MaterialPlugin::::default(), + )) + .add_systems(Startup, setup) + .add_systems(Update, rotate) + .run(); +} + +fn setup( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + commands.spawn(MaterialMeshBundle { + mesh: meshes.add( + Mesh::try_from(shape::UVSphere { + radius: 1.0, + ..default() + }).unwrap(), + ), + transform: Transform::from_xyz(0.0, 0.5, 0.0), + material: materials.add(ExtendedMaterial { + base: StandardMaterial { + base_color: Color::RED, + opaque_render_method: OpaqueRendererMethod::Forward, + alpha_mode: AlphaMode::Mask(0.5), + ..default() + }, + extension: MatExt { step: 3 }, + }), + ..default() + }); + + commands.spawn(PointLightBundle { + point_light: PointLight { + intensity: 10.0, + ..default() + }, + transform: Transform::from_xyz(-1.0, 4.5, 4.0).looking_at(Vec3::ZERO, Vec3::Y), + ..default() + }); + + commands.spawn(Camera3dBundle { + transform: Transform::from_xyz(-1.0, 1.5, 4.0).looking_at(Vec3::ZERO, Vec3::Y), + ..default() + }); +} + +#[derive(Asset, AsBindGroup, Reflect, Debug, Clone)] +struct MatExt { + #[uniform(100)] + step: u32, +} + +impl MaterialExtension for MatExt { + fn fragment_shader() -> ShaderRef { + "examples/shaders/dissolve.wgsl".into() + } + fn deferred_fragment_shader() -> ShaderRef { + "examples/shaders/dissolve.wgsl".into() + } +} + +fn rotate( + mut query: Query<&mut Transform, With>>, + time: Res