game: implement sprite color tinting (fixes )

This commit is contained in:
SeanOMik 2025-04-10 12:59:55 -04:00
parent d44eb3b5cf
commit b74cd7f30b
Signed by: SeanOMik
GPG key ID: FEC9E2FC15235964
6 changed files with 59 additions and 18 deletions
crates
lyra-game/src
lyra-scripting/src/lua/wrappers/sprite

View file

@ -415,19 +415,27 @@ impl Node for SpritePass {
}
}
// Get the transform accounting for the sprite pivot
let pivot = atlas_sprite
.as_ref()
.map(|ats| ats.0.pivot)
// 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();
let pivot_pos = dim.as_vec2() * (pivot - Vec2::splat(0.5));
let transform =
*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 {
atlas_frame: rect.unwrap_or(URect::ZERO),
transform: transform.calculate_mat4(),
color_tint: tint,
_padding: 0,
};
sprite_instances.push(inst);
let inst_id = sprite_instances.len() as u64 - 1;
@ -555,4 +563,6 @@ impl Node for SpritePass {
struct SpriteInstance {
atlas_frame: URect,
transform: glam::Mat4,
color_tint: glam::Vec3,
_padding: u32,
}

View file

@ -26,6 +26,7 @@ struct URect {
struct SpriteInstance {
atlas_frame: URect,
transform: mat4x4<f32>,
color: vec3<f32>,
}
struct CameraUniform {
@ -82,10 +83,13 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
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) {
discard;
}
// apply color tint
object_color = vec4<f32>(object_color.rgb * sprite.color.rgb, object_color.a);
return object_color;
}

View file

@ -38,7 +38,13 @@ impl SpriteAnimation {
/// * `frame_time` - The time per frame of the animation.
/// * `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.
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
I: Iterator<Item = u32>,
{
@ -96,14 +102,18 @@ impl AtlasAnimations {
pub fn from_animations(
atlas: ResHandle<TextureAtlas>,
animations: Vec<SpriteAnimation>,
sprite_pivot: Pivot
sprite_pivot: Pivot,
) -> Self {
let animations = animations
.into_iter()
.map(|a| (a.name.clone(), a))
.collect::<HashMap<_, _>>();
Self { atlas, animations, sprite_pivot }
Self {
atlas,
animations,
sprite_pivot,
}
}
/// Helper for creating [`AtlasAnimations`].
@ -140,7 +150,11 @@ impl AtlasAnimations {
.collect::<HashMap<_, _>>()
};
Self { atlas, animations, sprite_pivot }
Self {
atlas,
animations,
sprite_pivot,
}
}
/// Get the [`ActiveAtlasAnimation`] for an animation with `name`.
@ -282,6 +296,7 @@ fn system_animation_entity_impl(
atlas: animations.atlas.clone(),
sprite: rect,
pivot: animations.sprite_pivot,
..Default::default()
};
commands.insert(en, sprite);
@ -313,6 +328,7 @@ fn system_animation_entity_impl(
atlas: animations.atlas.clone(),
sprite: rect,
pivot: animations.sprite_pivot,
..Default::default()
};
let sprite = sprite.as_mut().unwrap();

View file

@ -1,4 +1,4 @@
use glam::UVec2;
use glam::{UVec2, Vec3};
use lyra_ecs::Component;
use lyra_math::URect;
use lyra_reflect::Reflect;
@ -49,12 +49,7 @@ impl TextureAtlas {
let start = (cell_size + padding) * UVec2::new(x, y) + offset;
let end = start + cell_size;
let r = URect::new(
start.x,
start.y,
end.x,
end.y,
);
let r = URect::new(start.x, start.y, end.x, end.y);
frames.push(r);
}
}
@ -83,6 +78,18 @@ pub struct AtlasSprite {
pub atlas: ResHandle<TextureAtlas>,
pub sprite: URect,
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 {
@ -102,6 +109,7 @@ impl AtlasSprite {
atlas: atlas.clone(),
sprite: rect,
pivot,
color: Vec3::ONE,
}
}
}

View file

@ -152,6 +152,7 @@ pub fn system_tilemap_update(
atlas: atlas_handle.clone(),
sprite: *frame,
pivot: super::Pivot::TopLeft,
..Default::default()
};
commands.insert(en, sprite);
@ -171,6 +172,7 @@ pub fn system_tilemap_update(
atlas: atlas_handle.clone(),
sprite: *frame,
pivot: super::Pivot::TopLeft,
..Default::default()
};
let grid = tile.tile.position * tile_size;

View file

@ -4,7 +4,7 @@ use lyra_scripting_derive::{to_lua_convert, wrap_lua_struct};
use super::LuaImageHandle;
use crate as lyra_scripting;
use crate::lua::wrappers::LuaVec2;
use crate::lua::wrappers::{LuaVec2, LuaVec3};
use crate::{
lua::wrappers::{helpers, LuaRect},
lyra_engine, ScriptEntity,
@ -65,6 +65,7 @@ to_lua_convert!(
atlas: wrap(LuaTextureAtlasHandle),
(sprite, wrap_with=helpers::wrap_urect_using_luarect),
(pivot, wrap_with=super::wrap_pivot_enum),
color: wrap(LuaVec3),
}
);