Implement a few more blend modes and switch to premultiplied alpha for layer
compositing
This commit is contained in:
parent
4933efb513
commit
36538d5748
|
@ -524,6 +524,11 @@ pub enum LineJoin {
|
|||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum CompositeOperation {
|
||||
SourceOver,
|
||||
DestinationOver,
|
||||
DestinationOut,
|
||||
SourceAtop,
|
||||
Xor,
|
||||
Lighter,
|
||||
Lighten,
|
||||
Darken,
|
||||
}
|
||||
|
@ -531,7 +536,12 @@ pub enum CompositeOperation {
|
|||
impl CompositeOperation {
|
||||
fn to_blend_mode(self) -> BlendMode {
|
||||
match self {
|
||||
CompositeOperation::SourceOver => BlendMode::SourceOver,
|
||||
CompositeOperation::SourceOver => BlendMode::SrcOver,
|
||||
CompositeOperation::DestinationOver => BlendMode::DestOver,
|
||||
CompositeOperation::DestinationOut => BlendMode::DestOut,
|
||||
CompositeOperation::SourceAtop => BlendMode::SrcAtop,
|
||||
CompositeOperation::Xor => BlendMode::Xor,
|
||||
CompositeOperation::Lighter => BlendMode::Lighter,
|
||||
CompositeOperation::Lighten => BlendMode::Lighten,
|
||||
CompositeOperation::Darken => BlendMode::Darken,
|
||||
}
|
||||
|
|
|
@ -58,14 +58,19 @@ pub enum Filter {
|
|||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum CompositeOp {
|
||||
/// The default.
|
||||
SourceOver,
|
||||
SrcOver,
|
||||
}
|
||||
|
||||
/// Blend modes that can be applied to individual paths without creating layers for them.
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub enum BlendMode {
|
||||
SourceOver,
|
||||
Clear,
|
||||
SrcOver,
|
||||
DestOver,
|
||||
DestOut,
|
||||
SrcAtop,
|
||||
Xor,
|
||||
Lighter,
|
||||
Lighten,
|
||||
Darken,
|
||||
}
|
||||
|
@ -76,25 +81,31 @@ pub struct DefringingKernel(pub [f32; 4]);
|
|||
impl Default for CompositeOp {
|
||||
#[inline]
|
||||
fn default() -> CompositeOp {
|
||||
CompositeOp::SourceOver
|
||||
CompositeOp::SrcOver
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BlendMode {
|
||||
#[inline]
|
||||
fn default() -> BlendMode {
|
||||
BlendMode::SourceOver
|
||||
BlendMode::SrcOver
|
||||
}
|
||||
}
|
||||
|
||||
impl BlendMode {
|
||||
/// Whether the backdrop is irrelevant when applying this blend mode (i.e. destination blend
|
||||
/// factor is zero).
|
||||
/// factor is zero when source alpha is one).
|
||||
#[inline]
|
||||
pub fn occludes_backdrop(self) -> bool {
|
||||
match self {
|
||||
BlendMode::SourceOver | BlendMode::Clear => true,
|
||||
BlendMode::Lighten | BlendMode::Darken => false,
|
||||
BlendMode::SrcOver | BlendMode::Clear => true,
|
||||
BlendMode::DestOver |
|
||||
BlendMode::DestOut |
|
||||
BlendMode::SrcAtop |
|
||||
BlendMode::Xor |
|
||||
BlendMode::Lighter |
|
||||
BlendMode::Lighten |
|
||||
BlendMode::Darken => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -965,6 +965,8 @@ impl BlendFactorExt for BlendFactor {
|
|||
BlendFactor::One => gl::ONE,
|
||||
BlendFactor::SrcAlpha => gl::SRC_ALPHA,
|
||||
BlendFactor::OneMinusSrcAlpha => gl::ONE_MINUS_SRC_ALPHA,
|
||||
BlendFactor::DestAlpha => gl::DST_ALPHA,
|
||||
BlendFactor::OneMinusDestAlpha => gl::ONE_MINUS_DST_ALPHA,
|
||||
BlendFactor::DestColor => gl::DST_COLOR,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,6 +226,8 @@ pub enum BlendFactor {
|
|||
One,
|
||||
SrcAlpha,
|
||||
OneMinusSrcAlpha,
|
||||
DestAlpha,
|
||||
OneMinusDestAlpha,
|
||||
DestColor,
|
||||
}
|
||||
|
||||
|
|
|
@ -1170,6 +1170,8 @@ impl BlendFactorExt for BlendFactor {
|
|||
BlendFactor::One => MTLBlendFactor::One,
|
||||
BlendFactor::SrcAlpha => MTLBlendFactor::SourceAlpha,
|
||||
BlendFactor::OneMinusSrcAlpha => MTLBlendFactor::OneMinusSourceAlpha,
|
||||
BlendFactor::DestAlpha => MTLBlendFactor::DestinationAlpha,
|
||||
BlendFactor::OneMinusDestAlpha => MTLBlendFactor::OneMinusDestinationAlpha,
|
||||
BlendFactor::DestColor => MTLBlendFactor::DestinationColor,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -762,7 +762,7 @@ where
|
|||
],
|
||||
viewport: self.draw_viewport(),
|
||||
options: RenderOptions {
|
||||
blend: Some(BlendMode::SourceOver.to_blend_state()),
|
||||
blend: Some(BlendMode::SrcOver.to_blend_state()),
|
||||
depth: Some(DepthState { func: DepthFunc::Less, write: false, }),
|
||||
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
|
||||
..RenderOptions::default()
|
||||
|
@ -848,7 +848,7 @@ where
|
|||
];
|
||||
|
||||
let blend_state = match composite_op {
|
||||
CompositeOp::SourceOver => BlendMode::SourceOver.to_blend_state(),
|
||||
CompositeOp::SrcOver => BlendMode::SrcOver.to_blend_state(),
|
||||
};
|
||||
|
||||
self.device.draw_elements(6, &RenderState {
|
||||
|
@ -1133,15 +1133,6 @@ trait BlendModeExt {
|
|||
impl BlendModeExt for BlendMode {
|
||||
fn to_blend_state(self) -> BlendState {
|
||||
match self {
|
||||
BlendMode::SourceOver => {
|
||||
BlendState {
|
||||
src_rgb_factor: BlendFactor::SrcAlpha,
|
||||
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
src_alpha_factor: BlendFactor::One,
|
||||
dest_alpha_factor: BlendFactor::One,
|
||||
..BlendState::default()
|
||||
}
|
||||
}
|
||||
BlendMode::Clear => {
|
||||
BlendState {
|
||||
src_rgb_factor: BlendFactor::Zero,
|
||||
|
@ -1151,9 +1142,63 @@ impl BlendModeExt for BlendMode {
|
|||
..BlendState::default()
|
||||
}
|
||||
}
|
||||
BlendMode::SrcOver => {
|
||||
BlendState {
|
||||
src_rgb_factor: BlendFactor::One,
|
||||
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
src_alpha_factor: BlendFactor::One,
|
||||
dest_alpha_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
..BlendState::default()
|
||||
}
|
||||
}
|
||||
BlendMode::DestOver => {
|
||||
BlendState {
|
||||
src_rgb_factor: BlendFactor::OneMinusDestAlpha,
|
||||
dest_rgb_factor: BlendFactor::DestAlpha,
|
||||
src_alpha_factor: BlendFactor::OneMinusDestAlpha,
|
||||
dest_alpha_factor: BlendFactor::One,
|
||||
..BlendState::default()
|
||||
}
|
||||
}
|
||||
BlendMode::DestOut => {
|
||||
BlendState {
|
||||
src_rgb_factor: BlendFactor::Zero,
|
||||
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
src_alpha_factor: BlendFactor::Zero,
|
||||
dest_alpha_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
..BlendState::default()
|
||||
}
|
||||
}
|
||||
BlendMode::SrcAtop => {
|
||||
BlendState {
|
||||
src_rgb_factor: BlendFactor::DestAlpha,
|
||||
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
src_alpha_factor: BlendFactor::DestAlpha,
|
||||
dest_alpha_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
..BlendState::default()
|
||||
}
|
||||
}
|
||||
BlendMode::Xor => {
|
||||
BlendState {
|
||||
src_rgb_factor: BlendFactor::OneMinusDestAlpha,
|
||||
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
src_alpha_factor: BlendFactor::OneMinusDestAlpha,
|
||||
dest_alpha_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
..BlendState::default()
|
||||
}
|
||||
}
|
||||
BlendMode::Lighter => {
|
||||
BlendState {
|
||||
src_rgb_factor: BlendFactor::One,
|
||||
dest_rgb_factor: BlendFactor::One,
|
||||
src_alpha_factor: BlendFactor::One,
|
||||
dest_alpha_factor: BlendFactor::One,
|
||||
..BlendState::default()
|
||||
}
|
||||
}
|
||||
BlendMode::Lighten => {
|
||||
BlendState {
|
||||
src_rgb_factor: BlendFactor::SrcAlpha,
|
||||
src_rgb_factor: BlendFactor::One,
|
||||
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
src_alpha_factor: BlendFactor::One,
|
||||
dest_alpha_factor: BlendFactor::One,
|
||||
|
@ -1162,7 +1207,7 @@ impl BlendModeExt for BlendMode {
|
|||
}
|
||||
BlendMode::Darken => {
|
||||
BlendState {
|
||||
src_rgb_factor: BlendFactor::SrcAlpha,
|
||||
src_rgb_factor: BlendFactor::One,
|
||||
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
|
||||
src_alpha_factor: BlendFactor::One,
|
||||
dest_alpha_factor: BlendFactor::One,
|
||||
|
|
|
@ -27,6 +27,8 @@ out vec4 oFragColor;
|
|||
void main(){
|
||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||
vec4 color = texture(uPaintTexture, vColorTexCoord);
|
||||
oFragColor = vec4(color . rgb, color . a * coverage);
|
||||
color . a *= coverage;
|
||||
color . rgb *= color . a;
|
||||
oFragColor = color;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,10 @@ fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuff
|
|||
main0_out out = {};
|
||||
float coverage = spvDescriptorSet0.uStencilTexture.sample(spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord).x;
|
||||
float4 color = spvDescriptorSet0.uPaintTexture.sample(spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
||||
out.oFragColor = float4(color.xyz, color.w * coverage);
|
||||
color.w *= coverage;
|
||||
float3 _41 = color.xyz * color.w;
|
||||
color = float4(_41.x, _41.y, _41.z, color.w);
|
||||
out.oFragColor = color;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,5 +25,7 @@ out vec4 oFragColor;
|
|||
void main() {
|
||||
float coverage = texture(uStencilTexture, vMaskTexCoord).r;
|
||||
vec4 color = texture(uPaintTexture, vColorTexCoord);
|
||||
oFragColor = vec4(color.rgb, color.a * coverage);
|
||||
color.a *= coverage;
|
||||
color.rgb *= color.a;
|
||||
oFragColor = color;
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ impl BuiltSVG {
|
|||
style,
|
||||
state.clip_path,
|
||||
fill_rule,
|
||||
BlendMode::SourceOver,
|
||||
BlendMode::SrcOver,
|
||||
name));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,7 +201,7 @@ pub fn draw_paths_into_scene(library: &SymbolLibrary, scene: &mut Scene) {
|
|||
paint_id,
|
||||
None,
|
||||
FillRule::EvenOdd,
|
||||
BlendMode::SourceOver,
|
||||
BlendMode::SrcOver,
|
||||
String::new()
|
||||
));
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ impl SceneExt for Scene {
|
|||
paint_id,
|
||||
None,
|
||||
FillRule::Winding,
|
||||
BlendMode::SourceOver,
|
||||
BlendMode::SrcOver,
|
||||
String::new()));
|
||||
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in New Issue