bevy/crates/bevy_pbr/src/alpha.rs

19 lines
548 B
Rust
Raw Normal View History

2021-11-22 23:16:36 +00:00
use bevy_ecs::{component::Component, reflect::ReflectComponent};
add `#[reflect(Default)]` to create default value for reflected types (#3733) ### Problem It currently isn't possible to construct the default value of a reflected type. Because of that, it isn't possible to use `add_component` of `ReflectComponent` to add a new component to an entity because you can't know what the initial value should be. ### Solution 1. add `ReflectDefault` type ```rust #[derive(Clone)] pub struct ReflectDefault { default: fn() -> Box<dyn Reflect>, } impl ReflectDefault { pub fn default(&self) -> Box<dyn Reflect> { (self.default)() } } impl<T: Reflect + Default> FromType<T> for ReflectDefault { fn from_type() -> Self { ReflectDefault { default: || Box::new(T::default()), } } } ``` 2. add `#[reflect(Default)]` to all component types that implement `Default` and are user facing (so not `ComputedSize`, `CubemapVisibleEntities` etc.) This makes it possible to add the default value of a component to an entity without any compile-time information: ```rust fn main() { let mut app = App::new(); app.register_type::<Camera>(); let type_registry = app.world.get_resource::<TypeRegistry>().unwrap(); let type_registry = type_registry.read(); let camera_registration = type_registry.get(std::any::TypeId::of::<Camera>()).unwrap(); let reflect_default = camera_registration.data::<ReflectDefault>().unwrap(); let reflect_component = camera_registration .data::<ReflectComponent>() .unwrap() .clone(); let default = reflect_default.default(); drop(type_registry); let entity = app.world.spawn().id(); reflect_component.add_component(&mut app.world, entity, &*default); let camera = app.world.entity(entity).get::<Camera>().unwrap(); dbg!(&camera); } ``` ### Open questions - should we have `ReflectDefault` or `ReflectFromWorld` or both?
2022-05-03 19:20:13 +00:00
use bevy_reflect::std_traits::ReflectDefault;
Add support for opaque, alpha mask, and alpha blend modes (#3072) # Objective Add depth prepass and support for opaque, alpha mask, and alpha blend modes for the 3D PBR target. ## Solution NOTE: This is based on top of #2861 frustum culling. Just lining it up to keep @cart loaded with the review train. 🚂 There are a lot of important details here. Big thanks to @cwfitzgerald of wgpu, naga, and rend3 fame for explaining how to do it properly! * An `AlphaMode` component is added that defines whether a material should be considered opaque, an alpha mask (with a cutoff value that defaults to 0.5, the same as glTF), or transparent and should be alpha blended * Two depth prepasses are added: * Opaque does a plain vertex stage * Alpha mask does the vertex stage but also a fragment stage that samples the colour for the fragment and discards if its alpha value is below the cutoff value * Both are sorted front to back, not that it matters for these passes. (Maybe there should be a way to skip sorting?) * Three main passes are added: * Opaque and alpha mask passes use a depth comparison function of Equal such that only the geometry that was closest is processed further, due to early-z testing * The transparent pass uses the Greater depth comparison function so that only transparent objects that are closer than anything opaque are rendered * The opaque fragment shading is as before except that alpha is explicitly set to 1.0 * Alpha mask fragment shading sets the alpha value to 1.0 if it is equal to or above the cutoff, as defined by glTF * Opaque and alpha mask are sorted front to back (again not that it matters as we will skip anything that is not equal... maybe sorting is no longer needed here?) * Transparent is sorted back to front. Transparent fragment shading uses the alpha blending over operator Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-11-16 03:03:27 +00:00
use bevy_reflect::Reflect;
// FIXME: This should probably be part of bevy_render2!
/// Alpha mode
#[derive(Component, Debug, Default, Reflect, Copy, Clone, PartialEq)]
add `#[reflect(Default)]` to create default value for reflected types (#3733) ### Problem It currently isn't possible to construct the default value of a reflected type. Because of that, it isn't possible to use `add_component` of `ReflectComponent` to add a new component to an entity because you can't know what the initial value should be. ### Solution 1. add `ReflectDefault` type ```rust #[derive(Clone)] pub struct ReflectDefault { default: fn() -> Box<dyn Reflect>, } impl ReflectDefault { pub fn default(&self) -> Box<dyn Reflect> { (self.default)() } } impl<T: Reflect + Default> FromType<T> for ReflectDefault { fn from_type() -> Self { ReflectDefault { default: || Box::new(T::default()), } } } ``` 2. add `#[reflect(Default)]` to all component types that implement `Default` and are user facing (so not `ComputedSize`, `CubemapVisibleEntities` etc.) This makes it possible to add the default value of a component to an entity without any compile-time information: ```rust fn main() { let mut app = App::new(); app.register_type::<Camera>(); let type_registry = app.world.get_resource::<TypeRegistry>().unwrap(); let type_registry = type_registry.read(); let camera_registration = type_registry.get(std::any::TypeId::of::<Camera>()).unwrap(); let reflect_default = camera_registration.data::<ReflectDefault>().unwrap(); let reflect_component = camera_registration .data::<ReflectComponent>() .unwrap() .clone(); let default = reflect_default.default(); drop(type_registry); let entity = app.world.spawn().id(); reflect_component.add_component(&mut app.world, entity, &*default); let camera = app.world.entity(entity).get::<Camera>().unwrap(); dbg!(&camera); } ``` ### Open questions - should we have `ReflectDefault` or `ReflectFromWorld` or both?
2022-05-03 19:20:13 +00:00
#[reflect(Component, Default)]
Add support for opaque, alpha mask, and alpha blend modes (#3072) # Objective Add depth prepass and support for opaque, alpha mask, and alpha blend modes for the 3D PBR target. ## Solution NOTE: This is based on top of #2861 frustum culling. Just lining it up to keep @cart loaded with the review train. 🚂 There are a lot of important details here. Big thanks to @cwfitzgerald of wgpu, naga, and rend3 fame for explaining how to do it properly! * An `AlphaMode` component is added that defines whether a material should be considered opaque, an alpha mask (with a cutoff value that defaults to 0.5, the same as glTF), or transparent and should be alpha blended * Two depth prepasses are added: * Opaque does a plain vertex stage * Alpha mask does the vertex stage but also a fragment stage that samples the colour for the fragment and discards if its alpha value is below the cutoff value * Both are sorted front to back, not that it matters for these passes. (Maybe there should be a way to skip sorting?) * Three main passes are added: * Opaque and alpha mask passes use a depth comparison function of Equal such that only the geometry that was closest is processed further, due to early-z testing * The transparent pass uses the Greater depth comparison function so that only transparent objects that are closer than anything opaque are rendered * The opaque fragment shading is as before except that alpha is explicitly set to 1.0 * Alpha mask fragment shading sets the alpha value to 1.0 if it is equal to or above the cutoff, as defined by glTF * Opaque and alpha mask are sorted front to back (again not that it matters as we will skip anything that is not equal... maybe sorting is no longer needed here?) * Transparent is sorted back to front. Transparent fragment shading uses the alpha blending over operator Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-11-16 03:03:27 +00:00
pub enum AlphaMode {
#[default]
Add support for opaque, alpha mask, and alpha blend modes (#3072) # Objective Add depth prepass and support for opaque, alpha mask, and alpha blend modes for the 3D PBR target. ## Solution NOTE: This is based on top of #2861 frustum culling. Just lining it up to keep @cart loaded with the review train. 🚂 There are a lot of important details here. Big thanks to @cwfitzgerald of wgpu, naga, and rend3 fame for explaining how to do it properly! * An `AlphaMode` component is added that defines whether a material should be considered opaque, an alpha mask (with a cutoff value that defaults to 0.5, the same as glTF), or transparent and should be alpha blended * Two depth prepasses are added: * Opaque does a plain vertex stage * Alpha mask does the vertex stage but also a fragment stage that samples the colour for the fragment and discards if its alpha value is below the cutoff value * Both are sorted front to back, not that it matters for these passes. (Maybe there should be a way to skip sorting?) * Three main passes are added: * Opaque and alpha mask passes use a depth comparison function of Equal such that only the geometry that was closest is processed further, due to early-z testing * The transparent pass uses the Greater depth comparison function so that only transparent objects that are closer than anything opaque are rendered * The opaque fragment shading is as before except that alpha is explicitly set to 1.0 * Alpha mask fragment shading sets the alpha value to 1.0 if it is equal to or above the cutoff, as defined by glTF * Opaque and alpha mask are sorted front to back (again not that it matters as we will skip anything that is not equal... maybe sorting is no longer needed here?) * Transparent is sorted back to front. Transparent fragment shading uses the alpha blending over operator Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-11-16 03:03:27 +00:00
Opaque,
/// An alpha cutoff must be supplied where alpha values >= the cutoff
/// will be fully opaque and < will be fully transparent
Mask(f32),
Blend,
}
impl Eq for AlphaMode {}