#[repr(C)]pub struct Decal3D {Show 16 fields
pub size: Vec3,
pub image: u32,
pub normal_image: u32,
pub uv_min: Vec2,
pub uv_max: Vec2,
pub color: Color,
pub opacity: f32,
pub normal_strength: f32,
pub roughness: f32,
pub metallic: f32,
pub angle_fade_start: f32,
pub angle_fade_end: f32,
pub depth_fade: f32,
pub max_distance: f32,
pub order: i32,
pub layers: u32,
}Expand description
A box that paints an image onto the opaque surfaces inside it. The
entity’s Transform3D places the box (its scale multiplies size).
The image is projected along the box’s -Z (looking from +Z), its top
along +Y, as with MeshData::decal; only
surfaces turned towards +Z get it.
Unlike a mesh decal, nothing is built: the decal is drawn onto whatever
is inside the box each frame, so it follows moving and skinned models,
costs the same however much geometry is under it, and is lit with the
surface it lands on. Put hundreds on screen (MAX_DECALS at most).
Parent a decal to a model (see Attached) to carry it along.
Images come from the texture array set with
Ctx::set_decal_textures; without
one a decal is a flat color rectangle. Surfaces whose model has no
matching ReceivesDecals layer are skipped, as are transparent
materials.
use ponko::*;
// A 2 x 2 m mark, 1 m deep, from the first image of the decal textures.
let mark = Decal3D { size: vec3(2.0, 2.0, 1.0), image: 0, ..Default::default() };
let mut world = World::new();
// Looking down: the box's +Z turned to point up.
let down = Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2);
world.spawn((Transform3D::at(vec3(0.0, 0.5, 0.0)).rotated(down), mark));Fields§
§size: Vec3Width (x), height (y) and depth (z) of the box, in world units.
Default (1, 1, 1).
image: u32The layer of the decal textures holding the color image, or
Decal3D::NO_IMAGE for a flat color. Colors are sRGB, as images
are painted. Default 0.
normal_image: u32The layer holding a tangent-space normal map, or Decal3D::NO_IMAGE
for none (the surface’s own normals). Default none.
uv_min: Vec2The top left of the image in its layer, as a fraction of it: use a
part of a layer as an atlas. Default (0, 0).
uv_max: Vec2The bottom right of the image in its layer. Default (1, 1).
color: ColorMultiplies the image (sRGB); its alpha multiplies opacity. Default
white.
opacity: f32How much of the decal shows, 0 to 1, times the image’s alpha. Default 1.
normal_strength: f32How strongly the normal map tilts the surface. Default 1.
roughness: f32The surface’s roughness where the decal is fully opaque, or a negative number to leave it as it is (the default). Wet blood is low, dust high.
metallic: f32The surface’s metallic value under the decal, or a negative number
to leave it (the default). Dirt on metal is 0.
angle_fade_start: f32Angle from the projection axis, in radians, up to which the decal is fully visible; beyond it, it fades out so it doesn’t stretch over steep surfaces. Default 1.0 (about 57 degrees).
angle_fade_end: f32Angle where it has faded out completely. Default 1.45 (about 83 degrees); surfaces at 90 degrees or more get none.
depth_fade: f32How much of the box’s depth, from each end, the decal fades over (0 to 1): 0 is a hard edge, 1 fades from the middle. Default 0.25.
max_distance: f32Distance from the camera past which the decal is not drawn; it fades out over the last quarter. 0 is unlimited (the default).
order: i32Decals with a higher order are drawn over those with a lower one. Equal orders keep the entities’ order in the world, which is not stable across despawns. Default 0.
layers: u32Which models get it: it shows on a model whose ReceivesDecals has
any of these bits. Only the low 16 bits count. Default all.
Implementations§
Trait Implementations§
impl Copy for Decal3D
Source§impl<'de> Deserialize<'de> for Decal3D
impl<'de> Deserialize<'de> for Decal3D
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl StructuralPartialEq for Decal3D
Auto Trait Implementations§
impl Forget for Decal3D
impl Freeze for Decal3D
impl RefUnwindSafe for Decal3D
impl Send for Decal3D
impl Sync for Decal3D
impl Unpin for Decal3D
impl UnsafeUnpin for Decal3D
impl UnwindSafe for Decal3D
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> Component for T
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
impl<T> MaybeSync for T
impl<T> MaybeSync for T
Source§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian().impl<T> Scalar for T
impl<T> SerializableAny for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.