Shdaow example + fixed shadows

Turns out one of the two things I fucked with caused the shadows to be
borked! What are the odds! (very high)
main
Elijah C. Voigt 1 year ago
parent bb2775b5eb
commit 5f3ed207fa

@ -0,0 +1,61 @@
// Source: https://github.com/bevyengine/bevy/blob/4f9f987099224ca41aab91a582b80fca8eb969f8/assets/shaders/extended_material.wgsl
#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<uniform> my_extended_material: MyExtendedMaterial;
@fragment
fn fragment(
in: VertexOutput,
@builtin(front_facing) is_front: bool,
) -> FragmentOutput {
// generate a PbrInput struct from the StandardMaterial bindings
var pbr_input = pbr_input_from_standard_material(in, is_front);
// we can optionally modify the input before lighting and alpha_discard is applied
pbr_input.material.base_color.b = pbr_input.material.base_color.r;
// 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);
// we can optionally modify the lit color before post-processing is applied
out.color = vec4<f32>(vec4<u32>(out.color * f32(my_extended_material.quantize_steps))) / f32(my_extended_material.quantize_steps);
// 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);
// we can optionally modify the final result here
out.color = out.color * 2.0;
#endif
return out;
}

@ -1,18 +1,42 @@
use bevy::prelude::*;
use bevy::{pbr::{ExtendedMaterial, MaterialExtension}, prelude::*, render::render_resource::{AsBindGroup, ShaderRef}};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(MaterialPlugin::<MonkeyMaterial>::default())
.insert_resource(Speed(0.3))
.add_systems(Startup, init)
.add_systems(Update, add_shadows)
.add_systems(Update, process_material)
.add_systems(Update, rotate_monkey)
.run();
}
fn init(server: Res<AssetServer>, mut commands: Commands) {
fn init(
server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut monkey_materials: ResMut<Assets<MonkeyMaterial>>,
mut commands: Commands
) {
commands.spawn(SceneBundle {
scene: server.load("models/shadow-example.gltf#Scene0"),
..default()
});
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(Sphere::new(1.0)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
material: monkey_materials.add(ExtendedMaterial {
base: StandardMaterial {
base_color: Color::RED.into(),
alpha_mode: AlphaMode::Mask(1.0),
..Default::default()
},
extension: MonkeyMaterialExtension { percentage: 0.5 },
}),
..default()
});
}
fn add_shadows(
@ -20,6 +44,7 @@ fn add_shadows(
mut commands: Commands,
) {
lights.iter_mut().for_each(|(e, mut l)| {
info!("Fixing up shadows");
l.shadows_enabled = true;
let config: bevy::pbr::CascadeShadowConfig =
@ -27,3 +52,69 @@ fn add_shadows(
commands.entity(e).insert(config);
});
}
type MonkeyMaterial = ExtendedMaterial<StandardMaterial, MonkeyMaterialExtension>;
#[derive(Asset, AsBindGroup, Reflect, Debug, Clone)]
struct MonkeyMaterialExtension {
#[uniform(100)]
percentage: f32,
}
impl MaterialExtension for MonkeyMaterialExtension {
fn fragment_shader() -> ShaderRef {
"shaders/dissolve.wgsl".into()
}
fn deferred_fragment_shader() -> ShaderRef {
"shaders/dissolve.wgsl".into()
}
}
fn process_material(
query: Query<(Entity, &Handle<StandardMaterial>, &Name), Added<Handle<StandardMaterial>>>,
base_materials: Res<Assets<StandardMaterial>>,
mut monkey_materials: ResMut<Assets<MonkeyMaterial>>,
mut commands: Commands,
) {
query.iter().for_each(|(e, h, n)| {
info!("Extended Materials");
let mut base = base_materials.get(h).unwrap().clone();
base.alpha_mode = AlphaMode::Mask(1.0);
// base.base_color = base.base_color.clone().with_a(0.0);
let extension = MonkeyMaterialExtension { percentage: 0.5 };
let monkey_material = monkey_materials.add(
ExtendedMaterial {
base, extension
}
);
commands
.entity(e)
.remove::<Handle<StandardMaterial>>()
.insert(monkey_material);
})
}
#[derive(Resource)]
struct Speed(f32);
fn rotate_monkey(
mut query: Query<(&mut Transform, &Name)>,
time: Res<Time>,
mut speed: ResMut<Speed>,
keys: Res<ButtonInput<KeyCode>>,
) {
if keys.just_pressed(KeyCode::ArrowUp) {
speed.0 *= 1.1;
} else if keys.just_pressed(KeyCode::ArrowDown) {
speed.0 *= 0.9;
}
query.iter_mut().for_each(|(mut t, n)| {
if *n == Name::new("Suzanne") {
t.rotate_local_y(time.delta_seconds() * speed.0)
}
});
}

@ -1106,6 +1106,10 @@ impl MaterialExtension for DissolveExtension {
fn fragment_shader() -> ShaderRef {
"shaders/dissolve.wgsl".into()
}
fn deferred_fragment_shader() -> ShaderRef {
"shaders/dissolve.wgsl".into()
}
}
/// Sets up all pieces to have an associated "dissolve" material ready for capture
@ -1150,8 +1154,8 @@ fn setup_dissolve_materials(
.expect("Resolve material data")
.clone();
base.alpha_mode = AlphaMode::Mask(0.5);
base.base_color = base.base_color.clone().with_a(0.0);
base.alpha_mode = AlphaMode::Mask(1.0);
// base.base_color = base.base_color.clone().with_a(0.0);
let dis_handle = dissolve_materials.add(ExtendedMaterial { base, extension });

Loading…
Cancel
Save