game: implement sprite color tinting (fixes #34)
This commit is contained in:
parent
d44eb3b5cf
commit
b74cd7f30b
6 changed files with 59 additions and 18 deletions
crates
lyra-game/src
render
sprite
lyra-scripting/src/lua/wrappers/sprite
|
@ -415,19 +415,27 @@ impl Node for SpritePass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the transform accounting for the sprite pivot
|
||||||
let pivot = atlas_sprite
|
let pivot = atlas_sprite
|
||||||
|
.as_ref()
|
||||||
.map(|ats| ats.0.pivot)
|
.map(|ats| ats.0.pivot)
|
||||||
// unwrap is safe since its either AtlasSprite or Sprite.
|
// unwrap is safe since its either AtlasSprite or Sprite.
|
||||||
.unwrap_or_else(|| sprite.unwrap().pivot)
|
.unwrap_or_else(|| sprite.as_ref().unwrap().pivot)
|
||||||
.as_vec();
|
.as_vec();
|
||||||
|
|
||||||
let pivot_pos = dim.as_vec2() * (pivot - Vec2::splat(0.5));
|
let pivot_pos = dim.as_vec2() * (pivot - Vec2::splat(0.5));
|
||||||
let transform =
|
let transform =
|
||||||
*transform + lyra_math::Transform::from_translation(pivot_pos.extend(0.0));
|
*transform + lyra_math::Transform::from_translation(pivot_pos.extend(0.0));
|
||||||
|
|
||||||
|
let tint = sprite
|
||||||
|
.map(|s| s.color)
|
||||||
|
.or_else(|| atlas_sprite.map(|(ats, _)| ats.color))
|
||||||
|
.unwrap_or(Vec3::ONE);
|
||||||
|
|
||||||
let inst = SpriteInstance {
|
let inst = SpriteInstance {
|
||||||
atlas_frame: rect.unwrap_or(URect::ZERO),
|
atlas_frame: rect.unwrap_or(URect::ZERO),
|
||||||
transform: transform.calculate_mat4(),
|
transform: transform.calculate_mat4(),
|
||||||
|
color_tint: tint,
|
||||||
|
_padding: 0,
|
||||||
};
|
};
|
||||||
sprite_instances.push(inst);
|
sprite_instances.push(inst);
|
||||||
let inst_id = sprite_instances.len() as u64 - 1;
|
let inst_id = sprite_instances.len() as u64 - 1;
|
||||||
|
@ -555,4 +563,6 @@ impl Node for SpritePass {
|
||||||
struct SpriteInstance {
|
struct SpriteInstance {
|
||||||
atlas_frame: URect,
|
atlas_frame: URect,
|
||||||
transform: glam::Mat4,
|
transform: glam::Mat4,
|
||||||
|
color_tint: glam::Vec3,
|
||||||
|
_padding: u32,
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct URect {
|
||||||
struct SpriteInstance {
|
struct SpriteInstance {
|
||||||
atlas_frame: URect,
|
atlas_frame: URect,
|
||||||
transform: mat4x4<f32>,
|
transform: mat4x4<f32>,
|
||||||
|
color: vec3<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CameraUniform {
|
struct CameraUniform {
|
||||||
|
@ -82,10 +83,13 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
region_coords /= dim;
|
region_coords /= dim;
|
||||||
}
|
}
|
||||||
|
|
||||||
let object_color: vec4<f32> = textureSample(t_diffuse, s_diffuse, region_coords);
|
var object_color: vec4<f32> = textureSample(t_diffuse, s_diffuse, region_coords);
|
||||||
if (object_color.a < ALPHA_CUTOFF) {
|
if (object_color.a < ALPHA_CUTOFF) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apply color tint
|
||||||
|
object_color = vec4<f32>(object_color.rgb * sprite.color.rgb, object_color.a);
|
||||||
|
|
||||||
return object_color;
|
return object_color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,13 @@ impl SpriteAnimation {
|
||||||
/// * `frame_time` - The time per frame of the animation.
|
/// * `frame_time` - The time per frame of the animation.
|
||||||
/// * `atlas` - The texture atlas that this animation is from, used to acquire `self.frames`.
|
/// * `atlas` - The texture atlas that this animation is from, used to acquire `self.frames`.
|
||||||
/// * `sprites` are the rect indexes in the atlas for this animation.
|
/// * `sprites` are the rect indexes in the atlas for this animation.
|
||||||
pub fn from_atlas<I>(name: &str, frame_time: f32, atlas: &TextureAtlas, auto_loop: bool, sprites: I) -> Self
|
pub fn from_atlas<I>(
|
||||||
|
name: &str,
|
||||||
|
frame_time: f32,
|
||||||
|
atlas: &TextureAtlas,
|
||||||
|
auto_loop: bool,
|
||||||
|
sprites: I,
|
||||||
|
) -> Self
|
||||||
where
|
where
|
||||||
I: Iterator<Item = u32>,
|
I: Iterator<Item = u32>,
|
||||||
{
|
{
|
||||||
|
@ -96,14 +102,18 @@ impl AtlasAnimations {
|
||||||
pub fn from_animations(
|
pub fn from_animations(
|
||||||
atlas: ResHandle<TextureAtlas>,
|
atlas: ResHandle<TextureAtlas>,
|
||||||
animations: Vec<SpriteAnimation>,
|
animations: Vec<SpriteAnimation>,
|
||||||
sprite_pivot: Pivot
|
sprite_pivot: Pivot,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let animations = animations
|
let animations = animations
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|a| (a.name.clone(), a))
|
.map(|a| (a.name.clone(), a))
|
||||||
.collect::<HashMap<_, _>>();
|
.collect::<HashMap<_, _>>();
|
||||||
|
|
||||||
Self { atlas, animations, sprite_pivot }
|
Self {
|
||||||
|
atlas,
|
||||||
|
animations,
|
||||||
|
sprite_pivot,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper for creating [`AtlasAnimations`].
|
/// Helper for creating [`AtlasAnimations`].
|
||||||
|
@ -140,7 +150,11 @@ impl AtlasAnimations {
|
||||||
.collect::<HashMap<_, _>>()
|
.collect::<HashMap<_, _>>()
|
||||||
};
|
};
|
||||||
|
|
||||||
Self { atlas, animations, sprite_pivot }
|
Self {
|
||||||
|
atlas,
|
||||||
|
animations,
|
||||||
|
sprite_pivot,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the [`ActiveAtlasAnimation`] for an animation with `name`.
|
/// Get the [`ActiveAtlasAnimation`] for an animation with `name`.
|
||||||
|
@ -282,6 +296,7 @@ fn system_animation_entity_impl(
|
||||||
atlas: animations.atlas.clone(),
|
atlas: animations.atlas.clone(),
|
||||||
sprite: rect,
|
sprite: rect,
|
||||||
pivot: animations.sprite_pivot,
|
pivot: animations.sprite_pivot,
|
||||||
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.insert(en, sprite);
|
commands.insert(en, sprite);
|
||||||
|
@ -313,6 +328,7 @@ fn system_animation_entity_impl(
|
||||||
atlas: animations.atlas.clone(),
|
atlas: animations.atlas.clone(),
|
||||||
sprite: rect,
|
sprite: rect,
|
||||||
pivot: animations.sprite_pivot,
|
pivot: animations.sprite_pivot,
|
||||||
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let sprite = sprite.as_mut().unwrap();
|
let sprite = sprite.as_mut().unwrap();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use glam::UVec2;
|
use glam::{UVec2, Vec3};
|
||||||
use lyra_ecs::Component;
|
use lyra_ecs::Component;
|
||||||
use lyra_math::URect;
|
use lyra_math::URect;
|
||||||
use lyra_reflect::Reflect;
|
use lyra_reflect::Reflect;
|
||||||
|
@ -15,7 +15,7 @@ pub struct TextureAtlas {
|
||||||
|
|
||||||
impl TextureAtlas {
|
impl TextureAtlas {
|
||||||
/// Create a texture atlas with rectangles of a grid.
|
/// Create a texture atlas with rectangles of a grid.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
/// * `texture` - The asset handle of the texture to get the sprites from.
|
/// * `texture` - The asset handle of the texture to get the sprites from.
|
||||||
/// * `grid_size` - The number of the cells in the grid (i.e., 9x7 grid).
|
/// * `grid_size` - The number of the cells in the grid (i.e., 9x7 grid).
|
||||||
|
@ -40,7 +40,7 @@ impl TextureAtlas {
|
||||||
if y > 0 {
|
if y > 0 {
|
||||||
p.y = padding.y;
|
p.y = padding.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in 0..grid_size.x {
|
for x in 0..grid_size.x {
|
||||||
if x > 0 {
|
if x > 0 {
|
||||||
p.x = padding.x;
|
p.x = padding.x;
|
||||||
|
@ -49,12 +49,7 @@ impl TextureAtlas {
|
||||||
let start = (cell_size + padding) * UVec2::new(x, y) + offset;
|
let start = (cell_size + padding) * UVec2::new(x, y) + offset;
|
||||||
let end = start + cell_size;
|
let end = start + cell_size;
|
||||||
|
|
||||||
let r = URect::new(
|
let r = URect::new(start.x, start.y, end.x, end.y);
|
||||||
start.x,
|
|
||||||
start.y,
|
|
||||||
end.x,
|
|
||||||
end.y,
|
|
||||||
);
|
|
||||||
frames.push(r);
|
frames.push(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,6 +78,18 @@ pub struct AtlasSprite {
|
||||||
pub atlas: ResHandle<TextureAtlas>,
|
pub atlas: ResHandle<TextureAtlas>,
|
||||||
pub sprite: URect,
|
pub sprite: URect,
|
||||||
pub pivot: Pivot,
|
pub pivot: Pivot,
|
||||||
|
pub color: Vec3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for AtlasSprite {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
atlas: Default::default(),
|
||||||
|
sprite: Default::default(),
|
||||||
|
pivot: Default::default(),
|
||||||
|
color: Vec3::ONE,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AtlasSprite {
|
impl AtlasSprite {
|
||||||
|
@ -102,6 +109,7 @@ impl AtlasSprite {
|
||||||
atlas: atlas.clone(),
|
atlas: atlas.clone(),
|
||||||
sprite: rect,
|
sprite: rect,
|
||||||
pivot,
|
pivot,
|
||||||
|
color: Vec3::ONE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,7 @@ pub fn system_tilemap_update(
|
||||||
atlas: atlas_handle.clone(),
|
atlas: atlas_handle.clone(),
|
||||||
sprite: *frame,
|
sprite: *frame,
|
||||||
pivot: super::Pivot::TopLeft,
|
pivot: super::Pivot::TopLeft,
|
||||||
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.insert(en, sprite);
|
commands.insert(en, sprite);
|
||||||
|
@ -171,6 +172,7 @@ pub fn system_tilemap_update(
|
||||||
atlas: atlas_handle.clone(),
|
atlas: atlas_handle.clone(),
|
||||||
sprite: *frame,
|
sprite: *frame,
|
||||||
pivot: super::Pivot::TopLeft,
|
pivot: super::Pivot::TopLeft,
|
||||||
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let grid = tile.tile.position * tile_size;
|
let grid = tile.tile.position * tile_size;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use lyra_scripting_derive::{to_lua_convert, wrap_lua_struct};
|
||||||
|
|
||||||
use super::LuaImageHandle;
|
use super::LuaImageHandle;
|
||||||
use crate as lyra_scripting;
|
use crate as lyra_scripting;
|
||||||
use crate::lua::wrappers::LuaVec2;
|
use crate::lua::wrappers::{LuaVec2, LuaVec3};
|
||||||
use crate::{
|
use crate::{
|
||||||
lua::wrappers::{helpers, LuaRect},
|
lua::wrappers::{helpers, LuaRect},
|
||||||
lyra_engine, ScriptEntity,
|
lyra_engine, ScriptEntity,
|
||||||
|
@ -65,6 +65,7 @@ to_lua_convert!(
|
||||||
atlas: wrap(LuaTextureAtlasHandle),
|
atlas: wrap(LuaTextureAtlasHandle),
|
||||||
(sprite, wrap_with=helpers::wrap_urect_using_luarect),
|
(sprite, wrap_with=helpers::wrap_urect_using_luarect),
|
||||||
(pivot, wrap_with=super::wrap_pivot_enum),
|
(pivot, wrap_with=super::wrap_pivot_enum),
|
||||||
|
color: wrap(LuaVec3),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue