2020-07-10 08:37:06 +00:00
|
|
|
use crate::{ColorMaterial, Sprite, TextureAtlas, TextureAtlasSprite};
|
2020-12-03 21:57:36 +00:00
|
|
|
use bevy_asset::{Assets, HandleUntyped};
|
2020-07-10 08:37:06 +00:00
|
|
|
use bevy_ecs::Resources;
|
2020-11-28 00:39:59 +00:00
|
|
|
use bevy_reflect::TypeUuid;
|
2020-05-30 19:31:04 +00:00
|
|
|
use bevy_render::{
|
2020-07-17 01:26:21 +00:00
|
|
|
pipeline::{
|
2021-02-01 04:06:42 +00:00
|
|
|
BlendFactor, BlendOperation, BlendState, ColorTargetState, ColorWrite, CompareFunction,
|
2021-02-05 04:17:11 +00:00
|
|
|
CullMode, DepthBiasState, DepthStencilState, FrontFace, PipelineDescriptor, PolygonMode,
|
|
|
|
PrimitiveState, PrimitiveTopology, StencilFaceState, StencilState,
|
2020-05-30 19:31:04 +00:00
|
|
|
},
|
2020-07-17 01:26:21 +00:00
|
|
|
render_graph::{base, AssetRenderResourcesNode, RenderGraph, RenderResourcesNode},
|
2020-05-30 19:31:04 +00:00
|
|
|
shader::{Shader, ShaderStage, ShaderStages},
|
|
|
|
texture::TextureFormat,
|
|
|
|
};
|
|
|
|
|
2020-12-03 21:57:36 +00:00
|
|
|
pub const SPRITE_PIPELINE_HANDLE: HandleUntyped =
|
|
|
|
HandleUntyped::weak_from_u64(PipelineDescriptor::TYPE_UUID, 2785347840338765446);
|
2020-05-30 19:31:04 +00:00
|
|
|
|
2020-12-03 21:57:36 +00:00
|
|
|
pub const SPRITE_SHEET_PIPELINE_HANDLE: HandleUntyped =
|
|
|
|
HandleUntyped::weak_from_u64(PipelineDescriptor::TYPE_UUID, 9016885805180281612);
|
2020-06-02 02:23:11 +00:00
|
|
|
|
|
|
|
pub fn build_sprite_sheet_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
|
|
|
PipelineDescriptor {
|
2021-02-01 04:06:42 +00:00
|
|
|
depth_stencil: Some(DepthStencilState {
|
2020-06-02 02:23:11 +00:00
|
|
|
format: TextureFormat::Depth32Float,
|
|
|
|
depth_write_enabled: true,
|
2020-08-28 23:45:54 +00:00
|
|
|
depth_compare: CompareFunction::LessEqual,
|
2021-02-01 04:06:42 +00:00
|
|
|
stencil: StencilState {
|
|
|
|
front: StencilFaceState::IGNORE,
|
|
|
|
back: StencilFaceState::IGNORE,
|
2020-08-13 20:58:36 +00:00
|
|
|
read_mask: 0,
|
|
|
|
write_mask: 0,
|
|
|
|
},
|
2021-02-01 04:06:42 +00:00
|
|
|
bias: DepthBiasState {
|
|
|
|
constant: 0,
|
|
|
|
slope_scale: 0.0,
|
|
|
|
clamp: 0.0,
|
|
|
|
},
|
|
|
|
clamp_depth: false,
|
2020-06-02 02:23:11 +00:00
|
|
|
}),
|
2021-02-01 04:06:42 +00:00
|
|
|
color_target_states: vec![ColorTargetState {
|
2020-10-16 18:44:31 +00:00
|
|
|
format: TextureFormat::default(),
|
2021-02-01 04:06:42 +00:00
|
|
|
color_blend: BlendState {
|
2020-06-02 02:23:11 +00:00
|
|
|
src_factor: BlendFactor::SrcAlpha,
|
|
|
|
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
|
|
|
operation: BlendOperation::Add,
|
|
|
|
},
|
2021-02-01 04:06:42 +00:00
|
|
|
alpha_blend: BlendState {
|
2020-06-02 02:23:11 +00:00
|
|
|
src_factor: BlendFactor::One,
|
|
|
|
dst_factor: BlendFactor::One,
|
|
|
|
operation: BlendOperation::Add,
|
|
|
|
},
|
|
|
|
write_mask: ColorWrite::ALL,
|
|
|
|
}],
|
2021-02-05 04:17:11 +00:00
|
|
|
primitive: PrimitiveState {
|
|
|
|
topology: PrimitiveTopology::TriangleList,
|
|
|
|
strip_index_format: None,
|
|
|
|
front_face: FrontFace::Ccw,
|
|
|
|
cull_mode: CullMode::None,
|
|
|
|
polygon_mode: PolygonMode::Fill,
|
|
|
|
},
|
2020-06-02 02:23:11 +00:00
|
|
|
..PipelineDescriptor::new(ShaderStages {
|
|
|
|
vertex: shaders.add(Shader::from_glsl(
|
|
|
|
ShaderStage::Vertex,
|
|
|
|
include_str!("sprite_sheet.vert"),
|
|
|
|
)),
|
|
|
|
fragment: Some(shaders.add(Shader::from_glsl(
|
|
|
|
ShaderStage::Fragment,
|
|
|
|
include_str!("sprite_sheet.frag"),
|
|
|
|
))),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-30 19:31:04 +00:00
|
|
|
pub fn build_sprite_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
|
|
|
PipelineDescriptor {
|
2021-02-01 04:06:42 +00:00
|
|
|
depth_stencil: Some(DepthStencilState {
|
2020-05-30 19:31:04 +00:00
|
|
|
format: TextureFormat::Depth32Float,
|
|
|
|
depth_write_enabled: true,
|
2020-08-28 23:45:54 +00:00
|
|
|
depth_compare: CompareFunction::LessEqual,
|
2021-02-01 04:06:42 +00:00
|
|
|
stencil: StencilState {
|
|
|
|
front: StencilFaceState::IGNORE,
|
|
|
|
back: StencilFaceState::IGNORE,
|
2020-08-13 20:58:36 +00:00
|
|
|
read_mask: 0,
|
|
|
|
write_mask: 0,
|
|
|
|
},
|
2021-02-01 04:06:42 +00:00
|
|
|
bias: DepthBiasState {
|
|
|
|
constant: 0,
|
|
|
|
slope_scale: 0.0,
|
|
|
|
clamp: 0.0,
|
|
|
|
},
|
|
|
|
clamp_depth: false,
|
2020-05-30 19:31:04 +00:00
|
|
|
}),
|
2021-02-01 04:06:42 +00:00
|
|
|
color_target_states: vec![ColorTargetState {
|
2020-10-16 18:44:31 +00:00
|
|
|
format: TextureFormat::default(),
|
2021-02-01 04:06:42 +00:00
|
|
|
color_blend: BlendState {
|
2020-05-30 19:31:04 +00:00
|
|
|
src_factor: BlendFactor::SrcAlpha,
|
|
|
|
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
|
|
|
operation: BlendOperation::Add,
|
|
|
|
},
|
2021-02-01 04:06:42 +00:00
|
|
|
alpha_blend: BlendState {
|
2020-05-30 19:31:04 +00:00
|
|
|
src_factor: BlendFactor::One,
|
|
|
|
dst_factor: BlendFactor::One,
|
|
|
|
operation: BlendOperation::Add,
|
|
|
|
},
|
|
|
|
write_mask: ColorWrite::ALL,
|
|
|
|
}],
|
2021-02-05 04:17:11 +00:00
|
|
|
primitive: PrimitiveState {
|
|
|
|
topology: PrimitiveTopology::TriangleList,
|
|
|
|
strip_index_format: None,
|
|
|
|
front_face: FrontFace::Ccw,
|
Add Sprite Flipping (#1407)
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
```rust
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the sprite along the x axis
flip: SpriteFlip { x: true, y: false },
..Default::default()
},
..Default::default()
});
```
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png)
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.
I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
2021-03-03 19:26:45 +00:00
|
|
|
cull_mode: CullMode::Back,
|
2021-02-05 04:17:11 +00:00
|
|
|
polygon_mode: PolygonMode::Fill,
|
|
|
|
},
|
2020-05-30 19:31:04 +00:00
|
|
|
..PipelineDescriptor::new(ShaderStages {
|
|
|
|
vertex: shaders.add(Shader::from_glsl(
|
|
|
|
ShaderStage::Vertex,
|
|
|
|
include_str!("sprite.vert"),
|
|
|
|
)),
|
|
|
|
fragment: Some(shaders.add(Shader::from_glsl(
|
|
|
|
ShaderStage::Fragment,
|
|
|
|
include_str!("sprite.frag"),
|
|
|
|
))),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub mod node {
|
2020-08-16 07:30:04 +00:00
|
|
|
pub const COLOR_MATERIAL: &str = "color_material";
|
|
|
|
pub const SPRITE: &str = "sprite";
|
|
|
|
pub const SPRITE_SHEET: &str = "sprite_sheet";
|
|
|
|
pub const SPRITE_SHEET_SPRITE: &str = "sprite_sheet_sprite";
|
2020-05-30 19:31:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait SpriteRenderGraphBuilder {
|
|
|
|
fn add_sprite_graph(&mut self, resources: &Resources) -> &mut Self;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SpriteRenderGraphBuilder for RenderGraph {
|
|
|
|
fn add_sprite_graph(&mut self, resources: &Resources) -> &mut Self {
|
|
|
|
self.add_system_node(
|
|
|
|
node::COLOR_MATERIAL,
|
2020-06-11 01:54:17 +00:00
|
|
|
AssetRenderResourcesNode::<ColorMaterial>::new(false),
|
2020-05-30 19:31:04 +00:00
|
|
|
);
|
2020-07-17 01:26:21 +00:00
|
|
|
self.add_node_edge(node::COLOR_MATERIAL, base::node::MAIN_PASS)
|
2020-05-30 19:31:04 +00:00
|
|
|
.unwrap();
|
|
|
|
|
2020-06-22 19:14:40 +00:00
|
|
|
self.add_system_node(node::SPRITE, RenderResourcesNode::<Sprite>::new(true));
|
2020-07-17 01:26:21 +00:00
|
|
|
self.add_node_edge(node::SPRITE, base::node::MAIN_PASS)
|
2020-06-22 19:14:40 +00:00
|
|
|
.unwrap();
|
2020-05-30 19:31:04 +00:00
|
|
|
|
2020-06-03 18:39:10 +00:00
|
|
|
self.add_system_node(
|
|
|
|
node::SPRITE_SHEET,
|
2020-06-11 01:54:17 +00:00
|
|
|
AssetRenderResourcesNode::<TextureAtlas>::new(false),
|
2020-06-03 18:39:10 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
self.add_system_node(
|
|
|
|
node::SPRITE_SHEET_SPRITE,
|
2020-06-11 01:54:17 +00:00
|
|
|
RenderResourcesNode::<TextureAtlasSprite>::new(true),
|
2020-06-03 18:39:10 +00:00
|
|
|
);
|
|
|
|
|
2020-05-30 19:31:04 +00:00
|
|
|
let mut pipelines = resources.get_mut::<Assets<PipelineDescriptor>>().unwrap();
|
|
|
|
let mut shaders = resources.get_mut::<Assets<Shader>>().unwrap();
|
2020-10-18 20:48:15 +00:00
|
|
|
pipelines.set_untracked(SPRITE_PIPELINE_HANDLE, build_sprite_pipeline(&mut shaders));
|
|
|
|
pipelines.set_untracked(
|
2020-06-04 03:08:20 +00:00
|
|
|
SPRITE_SHEET_PIPELINE_HANDLE,
|
|
|
|
build_sprite_sheet_pipeline(&mut shaders),
|
|
|
|
);
|
2020-05-30 19:31:04 +00:00
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|